强参数和attr_accessible都存在的基本安全原因是模型中的某些属性不应被允许更改,除非它是您的代码的明确意图。
他们之间的细微差别是他们工作的透视形式。
StrongParameters专注于用例:考虑到任何条件,每个控制器的操作都可以微调以允许或禁止某些参数。完全的灵活性。
attr_accessible采取不同的观点。它不是专注于用例,而是专注于角色。例如,根据用户的角色,某些属性可以更改或不更改。
使用StrongParameters的方法是在参数哈希上应用require
andpermit
关键字。
require
声明一个键必须存在于 params 散列中。require
如果没有这样的密钥,将引发异常。
permit
声明一个字段是允许的。任何不允许的键都将从散列中删除,因此不会通过批量分配的方式传递给模型。
模型
class League
attr_protected :final_price # Nobody can mass-assign the final price
attr_accessible :winner_name, :as => :jury
end
和控制器
class LeaguesController < ApplicationController
这两个动作使用StrongParameters
# A common user can create a league
def create
league = League.new(league_params)
league.final_price = 1000
league.save
redirect_to(league)
end
# But only the admin can publish a league
def publish_league
league = League.find(params[:id]
league.update_attributes(league_params_as_admin)
end
这个使用attr_accessible
def publish_the_winner
league = League.find(params[:id]
# We would expect the current_user.role to return :jury.
league.assign_attributes(params[:league], :as => current_user.role)
end
private
def league_params
params.require(:league).permit(:name)
end
def league_params_as_admin
params.require(:league).permit(:name, :status)
end
end
在我的经验中:
使用强参数的灵活性来微调可以在每个控制器中批量分配的属性。
使用 attr_accesible 的无所不在确保某些属性无论如何都不能被大量分配。例如,在 Resque 任务中,您可以将用户输入作为参数传递。您将使用 attr_accesible 检查某些属性是否未批量分配。
更多信息:
http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html
https://github.com/rails/strong_parameters