mass assignment と strong parameters
私なりの解釈
mass assignment #=> assign すべきではない物もしてしまう仕組み及び方法
strong parameters #=> mass assignment を防ぐ手段
以下、詳しく
前置き
例えば User モデル(権限つき)の attribute が次の通りであるとする
name:string, email:string, admin:boolean
update_attributes の方法は 例えば update メソッド内で
今まで(Rails3 系)
params[:user] #=> {name: 'matsu', email: 'matsu@matsu.matsu'} # 管理者用の admin は params に入っていない user = User.update_attributes(params[:user])
で通っていたが
これから(Rails4 系)
def user_params params.require(:user).permit(:name, :email) end user = User.update_attributes(params[:user])
にしないといけない
何が理由で
一言ならば、クラッキングを防ぐため。
今までの実装方法なら、次のようなURIを指定する方法で
admin の attribute も更新をかけることができる。
PUT /users/2?user[name]=nowadmin&user[admin]=1 User.update_attributes(params[:user]) params[:user] #=> {"name": "nowadmin", "admin": "1"} user id == 2 に該当する user の admin が true になった。
対策
主にController 側で対策をとる(Model 側もあるらしいが、読みきれていない)
params のホワイトリストをつくる。
params.require(:user).permit(:name, :email) # POST/PUTで name:'foo', email:'foo@foo.com', admin:1 にしても # {name: 'foo', email: 'foo@foo.com'} がオブジェクトとして返ってくる --- def user_params params.require(:user).permit(:name, :email) end User.update_attributes(user_params)
管理者/非管理者で切り分けしたい時は次の方法が取れる。
def user_params if admin_user? params.require(:user).permit(:name, :email, :admin) else params.require(:user).permit(:name, :email) end end
引用元
http://www.sitepoint.com/rails-4-quick-look-strong-parameters/