Goal
-
new
,create
,update
などでattributesハッシュを渡したときに引数attributesに対して毎回特定のフィルタ処理をおこないたい - 通常はモデルの仕様に合わせて呼び出し側でattributesを準備するべきだと思うが、準備すべき引数attributesがモデルのビジネスロジックに依存する場合、利便性のためにモデル側にパラメータ変換ロジックを持たせておきたい
Code
assign_attributes
をオーバーライドすればよい. new
, create
, update
で渡された引数attributesはassign_attributes
メソッドを通してモデルにセットされる.
user.rb
class User < ActiveRecord::Base
belongs_to :game
def self.gender_role( role_name, gender_name )
gender_roles = {
acting: {
male: :actor,
female: :actress,
},
waiting: {
male: :waiter,
female: :waitress,
}
}
return nil unless gender_roles[role_name]
gender_roles[role_name][gender_name]
end
def assign_attributes(attributes)
gender_local = gender
gender_local = attributes[:gender] if attributes[:gender]
attributes[:role] = User.gender_role(attributes[:role], gender_local)
super attributes
end
end
user = User.new( role: :acting, gender: :male )
user.role # :actor
user = User.new( role: :acting, gender: :female )
user.role # : actress
user = User.create( gender: :male )
user.update( role: :waiting )
user.role # :waiter
Caution
引数つきでnew
したときは毎回実行されるので、重い処理を実行するときは注意.
個別のattributeに直接代入するときは当然assign_attributes
はよばれない.
Environment
$ bundle exec rails -v
Rails 4.1.9