我正在努力实现多态评论(这些几乎可以应用于网站上的任何用户内容,并且不限于 Article
实例。创建评论时,我需要确定它属于哪个 commentable
。大部分写作我have found on this subject 建议我在下面的代码中使用 find_commentable
中指定的模式,但这种方法并没有让我觉得非常优雅 - 似乎应该有一种直接的方法来明确指定 commentable
正在创建新注释for,不遍历params
集,不进行字符串匹配,有没有更好的方法?
换句话说,在 commentable
→ comment
关联的上下文中,是否有更好的方法从 commentable
Controller 访问 comment
对象?在我们还没有 create
对象可以使用的 @comment
方法中,它是否仍然有效?
我的模型设置如下:
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's Article on Polymorphic Associations,因为我觉得它提供了最简洁的解释。
对于您的应用程序,还有两个附加选项:
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