Red > Green > Refactor > Red

cycle is based on desire

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/