我正致力于实现多态注释(这些注释可以应用于网站上的任何用户内容,并不仅限于Article
实例.在创建注释时,我需要确定commentable
它属于哪个.我发现的大部分文字关于这个问题建议我使用find_commentable
下面代码中指定的模式,但这种方法并没有让我觉得非常优雅 - 似乎应该有一种直接的方式来明确指定commentable
正在创建的新注释,而不需要遍历该params
集,并且没有字符串匹配,有没有更好的办法?
换句话说,是否有更好的方法在→ 关联的上下文中commentable
从comment
控制器访问对象?它仍然可以使用我们还没有一个对象可以使用的方法吗?commentable
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关于多态关联的文章,因为我觉得它提供了最简洁的解释.
对于您的应用,还有两个选项:
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