簡體   English   中英

在rails多態關聯中查找父級

[英]finding parent in rails polymorphic association

我正致力於實現多態注釋(這些注釋可以應用於網站上的任何用戶內容,並且不僅限於Article實例。在創建注釋時,我需要確定它屬於哪個可commentable 。大多數寫作我我已經在這個問題上發現我在下面的代碼中使用了find_commentable中指定的模式,但是這種方法並沒有讓我覺得非常優雅 - 似乎應該有一種直接的方法來明確指定可commentable的新注釋正在被創建因為,沒有遍歷params集,沒有字符串匹配。有更好的方法嗎?

換句話說,是否有更好的方法在commentablecomment關聯的上下文中從comment控制器訪問可commentable對象? 它仍然適用於我們尚未使用@comment對象的create方法嗎?

我的模型設置如下:

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

謝謝!

我也在尋找答案,並希望分享Launch Academy關於多態關聯的文章,因為我覺得它提供了最簡潔的解釋。
對於您的應用,還有兩個選項:

1.“Ryan Bates”方法:(當您使用Rails的傳統RESTful URL時)

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

我會反過來做 - 然后讓評論定義可評論。

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

我接受了Ryan Bates的想法,並稍微調整了一下。 我有一些更深入的范圍和嵌套資源。

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

這里的想法是你從路徑的末尾剝離父母。

因此,如果你的路徑是/scope/resource_a/1234/resource_b/5678/comments等,無論你有多深,你總是得到頂級父級。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM