Open4

パーフェクトrails 11-2 値オブジェクトについて

masamasa

def 関数名=(引数)はセッターとしての書き方
Userモデルの中で、def phone_number=(new_phone_number)が定義されていれば、
user_object.phone_number = new_phone_numberとすることで、new_phone_numberが新しい値として代入することができる。

masamasa

compose_ofの使い方

  • composed_of '属性名', mapping %w['model' '値オブジェクト']
  • 第一引数は呼び出し元のモデルの属性名
  • 第二引数は、値オブジェクトのモデル名、対応する値オブジェクトをmappingで指定する
masamasa

上記のように書くと、指定した属性の値はオブジェクトとなる。

例:Userモデルに、composed_of :hoge, mapping: %[hoge fuga]としている場合

  • setterとして使用する場合
    • User.new(hoge: hoge_instance)
  • getterとして取得する場合
    • User.hoge.fuga
masamasa

composed_ofのオプション

## phone_number :string
class User < ApplicationRecord
composed_of :phone_number,
    mapping: %w[phone_number value],
    class_name: 'phone_number' ## composed_ofと同じのため省略可
    constructor: Proc.new { |value| PhoneNumber.new(value) },
    converter: Proc.new { |value| PhoneNumber.new(value.to_s) }
  • composed_of
    • 値オブジェクトが格納される属性の名前
  • class_name
    • 値オブジェクトを作成する際に使用するクラス名
    • composed_ofで指定した属性の名前と同じであれば省略可
  • mapping
    • モデルと値オブジェクトを相対させる
    • 上記例だと、Userモデルのphone_numberとPhoneNumberクラスのvalueを相対づけている。
  • constructor
    • Userインスタンス作成時に、値オブジェクトをどのように作成するかの処理。
    • Proc.new { |value| PhoneNumber.new(value) }により、mappingでphone_numberとvalueが紐づいているため、User.new(phone_number: '090xxxxxxxx')とすると、この値がvalueに渡され、PhoneNumberクラスのオブジェクトがデフォルトでphone_numberの値となる。
    • 上記のconstructorを指定しなければ、User.new(phone_number: PhoneNumber.new(phone_number: "090xxxxxxxx"))とインスタンスを作成して渡さないといけないので面倒