我的生产代码中往往不需要mass-assignment功能。 (在我的测试代码中,我经常使用它,但在那些情况下,我做想要设置任意列。)
因此,如果在我的生产代码中,我只是避免使用这些形式:
Article.new(params[:article]) # or create
article.attributes = params[:article]
article.update_attributes(params[:article])
而是始终手动枚举所有属性,如下所示:
Article.new(:title => params[:article][:title], :body => params[:article][:body], ...)
我是否从质量分配安全问题中解决了问题(即使不使用attr_accessible
/ attr_protected
)?
编辑:我不仅仅禁用批量分配的原因是,我希望能够编写Article.create!(:blog_id => @blog.id, ...)
,其中blog_id是一个“未保存”属性。
答案 0 :(得分:10)
是的,使用第二种方法,您可以安全地从用户分配其他属性。
这是一种干燥的写作方式,但是:
Article.new(params[:article].slice(:title, :body))
-OR -
def article_params
params[:article].slice(:title, :body)
end
Article.new(article_params) # or create
article.attributes = article_params
article.update_attributes(article_params)
答案 1 :(得分:2)
在config/environments/production.rb
:
ActiveRecord::Base.send(:attr_accessible, nil)
答案 2 :(得分:0)
我无法让John Douthat的方法为多个参数工作,所以我想出了以下替代方案(取自我的CommentsController):
def set_params
@comment.parent_id = params[:blog_comment][:parent_id]
@comment.ip_address = request.remote_ip
@comment.commentator = current_user.username || "anonymous"
@comment.name = params[:blog_comment][:name]
@comment.email = params[:blog_comment][:email]
@comment.url = params[:blog_comment][:url]
end
def create
@comment = @post.comments.build(params[:blog_comment])
set_params
if @comment.save
...
end
def update
@comment = Blog::Comment.find(params[:id])
set_params
if @comment.update_attributes(params[:blog_comment])
...
end