今週のrailscasts - Dynamic attr_accessible
Railscasts - Dynamic attr_accessible
ASCIIcasts - “Episode 237 - Dynamic attr_accessible”
を見て。
attr_accessibleメソッドの欠点2つ
- テスト時に mass assign したいけど attr_accessibleでできない><
- 動的でないので、ユーザの権限によってaccessibleな属性を変更するみたいなことが出来ない><
2つめの欠点は自分にとってかなり致命的で、個人的に attr_accessible はほとんど使ってない><
Rails 3 で mass assignment
attr_accessible は、Rails 3 では ActiveModel::MassAssignmentSecurity module に含まれている。なのでActiveRecord以外でも使える。controller に include して、admin ユーザなら accessible な属性を増やすような使い方も出来る。下記はrails の document から引用。
class AccountsController < ApplicationController include ActiveModel::MassAssignmentSecurity attr_accessible :first_name, :last_name def self.admin_accessible_attributes accessible_attributes + [ :plan_id ] end def update ... @account.update_attributes(account_params) ... end protected def account_params sanitize_for_mass_assignment(params[:account]) end def mass_assignment_authorizer admin ? admin_accessible_attributes : super end end
mass_assignment_authorizer メソッドをオーバライドすることで、mass assignmentを許可するカラムを条件毎に変化させられる。
rails のドキュメントでは controller のみで動的な mass assignment を実現してたけど、railscasts 中では、model に accessible というインスタンス変数を追加し、controller の action 毎に 属性名 を代入することで動的な mass assignment を実現してた。さらに最終的には config/initializers ディレクトリで ActiveRecord::Base を拡張して、全 model に変更を反映させていた。
気になった細かい点
- protected_attributes メソッドで protected な attributesの配列がとれる
- これもMassAssignmentSecurity Moduleで定義されているメソッド
- 引数なしの attr_accessible は全部 protected にしたのと同じ
- attr_accessible は二回呼んでもいい
- 二回以上呼んだ場合は単純にaccessibleな属性が足されるっぽい