LoginSignup
3
2

More than 5 years have passed since last update.

Rails4 attributeの代入をフックする

Posted at

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
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2