Rails 4附带了strong_parameters,这是一个很好的补充 - 但我遇到了一个问题。我有一个多态模型Comment
,我不能在我的生活中让控制器接受它需要的参数。这是我的代码(为了清楚起见缩短了):
路线:
resources :articles do
resources :comments
end
模特:
class Article < ActiveRecord::Base
has_many :comments, :as => :commentable
end
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
end
控制器:
class CommentsController < ApplicationController
before_action :get_commentable
def create
@comment = @commentable.comments.new(comment_params)
if @comment.save
redirect_to @commentable, :notice => "Thank you!"
else
render :new
end
end
private
def get_commentable
resource, id = request.path.split("/")[1,2]
@commentable = resource.singularize.classify.constantize.find(id)
redirect_to :home unless defined?(@commentable)
end
def comment_params
params.require(:comment).permit(:title, :message)
end
end
发布params(来自文章#show的表格):
{"authenticity_token"=>"v70nN8aFpofNw9vbVjhpsm9SwLOwKlOpNOEOTozUwCk=",
"comment"=>{"title"=>"Test","message"=>"Testing"},
"article_id"=>"1"}
在我看来它应该可行,但无论我尝试什么,我都会ActiveModel::ForbiddenAttributesError in CommentsController#create
- 即使我尝试
def comment_params
params.permit!
end
在控制器中。我的其他(非多态)模型没有这样的问题,这就是为什么我怀疑它与多态性有关。有任何想法吗?
答案 0 :(得分:2)
由于缺乏答案似乎表明我在这里咆哮着错误的树。问题不在于strong_parameters,而在于我用于基于角色和操作的授权的CanCan gem。显然,它与CanCan如何将params分配给对象(CanCan接管默认的ActionController方法)有关 - 请参阅this bug report中的详细信息,特别是the reply from "rewritten"。简而言之,将它放在我的应用程序控制器中解决了这个问题:
before_filter do
resource = controller_name.singularize.to_sym
method = "#{resource}_params"
params[resource] &&= send(method) if respond_to?(method, true)
end
<强>更新强>
正如@scaryguy所指出的,如果从没有关联模型的控制器调用上述方法,它将会失效。解决方案只是命名方法并将其称为before_filter,同时在那些没有模型的控制器中明确排除它(因此无论如何都不会从CanCan的自动能力分配中受益)。我估计这样的事情:
before_filter :can_can_can
def can_can_can
resource = controller_name.singularize.to_sym
method = "#{resource}_params"
params[resource] &&= send(method) if respond_to?(method, true)
end
然后在无模型控制器中:
skip_before_filter :can_can_can