LoginSignup
18
20

More than 5 years have passed since last update.

ActiveRecord の serializable_hash の使い方

Last updated at Posted at 2015-08-05

動機

  • ロジックの分離、疎結合化を進めたかった。
    • 切り出し先ではデータベースアクセスを一切させない!
    • すべてのデータを引数渡し!
    • ステートレス!
    • テストしやすく!
    • 独立性を確保!
  • そのため、次の流れで進めることにした。
    1. 呼び出し元ですべてのデータ取得を事前に行う。
    2. 必要な全データをシリアライズして、切り出し先に引数で渡す。
    3. 受け取ったデータに対して必要な処理を行う。(データベースアクセスなし)
  • serializable_hashas_json の日本語情報があまりなく、備忘録として本記事を執筆しようと思った。

serializable_hash の使い方

特定の属性だけ、含めたいとき

selfActiveRecord オブジェクトであることが前提。

  self.serializable_hash(
    only: %w(name gender age)
  )

特定の属性を除きたいとき

  self.serializable_hash(
    except: %w(id created_at updated_at)
  )

特定のメソッドの実行結果を serialize 結果に含めたいとき

  def price_with_currency
    "%5.2f 円" % self.price
  end

  def serialize_for_discount_logic
    self.serializable_hash(
      except: %w(id created_at updated_at),
      methods: %w(price_with_currency)
    )
  end

Association 先を含めたいとき

class Order < ActiveRecord::Base
  belongs_to :customer

  def serialize_with_the_buyer_full
    self.serializable_hash(
      include: customer
    )
  end
end

Association 先でもシリアライズする属性を指定したいとき。

class Order < ActiveRecord::Base
  belongs_to :customer

  def serialize_with_the_buyer_partial
    self.serializable_hash(
      include: {
        customer: {
          except: %w(id created_at updated_at)
        }
      }
    )
  end
end

属性取得方法をカスタマイズしたいとき

read_attribute_for_serialization をオーバーライドすると、属性の取得方法をカスタマイズできる。
デフォルトは Object#sendattr_accessor を使っている場合など、通常の利用では、このオーバーライドは不要。

逆に getter を定義しない場合とかに便利。

person.rb
class Person
  include ActiveModel::Model
  include ActiveModel::Serialization

  def initialize(data = {})
    @data = data
  end

  def age= age
    @data["age"] = age
  end

  def read_attribute_for_serialization(key)
    @data[key]
  end

  def attributes
    @data.dup
  end
end

person = Person.new
person.age = 20

person.serializable_hash()

as_json の話

as_json メソンドは実は serializable_hash のうすいラッパーなので、上記で書いているのは、 as_json でもあてはまります。

18
20
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
18
20