Parent search in rails of polymorphic association

I am working on the implementation of polymorphic comments (they can be applied to almost any user-generated content on the site and are not limited to instances Article. When creating a comment, I need to determine which one commentableit belongs to. Most of the letters that I found on this subject suggest that I I use the template specified in the find_commentablecode below, but this approach does not seem very elegant to me - it would seem that there should be a simple way to unambiguously indicate the commentablecreated new comment, without going through the set paramsand without matching with Is there a better way?

In other words, there is a better way to access the object commentablefrom the controller commentin the context of commentable→ commentassociation? It still works with a method create, where we still do not have an object @commentto work with?

My models are configured as follows:

class Comment < ActiveRecord::Base
  belongs_to :commentable, :polymorphic => true
end

class Article < ActiveRecord::Base
  has_many :comments, :as => :commentable, dependent: :destroy
end

class CommentsController < ApplicationController 
  def create
    @commentable = find_commentable  
    @comment = @commentable.comments.build(comment_params)

    if @comment.save
      redirect_to :back
    else  
      render :action => 'new'
    end  
  end

  def index
    @commentable = find_commentable
    @comments = @commentable.comments
  end

  private
    def comment_params
      params.require(:comment).permit(:body)
    end

    def find_commentable
      params.each do |name, value|
        if name =~ /(.+)_id$/
          return $1.classify.constantize.find(value)
        end
    end
  end
end

Thank!

+4
source share
3 answers

I also searched for the answer to this question and wanted to share the Run Academy article on polymorphic associations as I felt that this gives the most concise explanation.
Two additional options are available for your application:

1. " ": ( RESTful- Rails)

def find_commentable
    resource, id = request.path.split('/')[1, 2]
    @commentable = resource.singularize.classify.constantize.find(id)
end

2. :

def find_commentable
    commentable = []
    params.each do |name, value|
      if name =~ /(.+)_id$/
        commentable.push($1.classify.constantize.find(value))
      end
    end
    return commentable[0], commentable[1] if commentable.length > 1
    return commentable[0], nil if commentable.length == 1
    nil
end

3. : ( , )

def find_commentable
  params.each do |name, value|
    if name =~ /(.+)_id$/
      return $1.classify.constantize.find(value)
    end
  end
  nil
end
+8

- , .

@comment = Comment.create(params[:comment]) #this is the standard controller code for create
@commentable = @comment.commentable
+5

. .

id, resource = request.path.split('/').reverse[1,2]
@commentable = resource.singularize.classify.constantize.friendly.find(id)

, .

, /scope/resource_a/1234/resource_b/5678/comments .., , , .

+1

Source: https://habr.com/ru/post/1536628/


All Articles