Ruby/RailsでのBuilder Patternについて少し進んだ

photo credit: Andrew* via photopin cc

以前、以下の指摘を受けたと書いた。

それか builder pattern を使ってこんな感じで。

link = Api::Link.build do
  id = 'x'
  title = 'y'
  url = 'z'
end

いずれにしても一つ一つ設定しない方法がスマートです。

で、色々試行錯誤して、以下のように出来た。

@api = Api::PanelApi.build do
  self.id = '999'
  self.title = 'サンプルタイトル'
  self.url = '//www.example.com/'
  self.left_panel = build_panel do
    self.priority = 'normal'
    self.template_type = 'template'
    self.title = 'サンプルタイトル'
    add_link do
      self.id = 'left-sample1'
      self.title = 'left-title-sample1'
      self.url = '//www.example.com/'
      add_image do
        self.width = 200
        self.height = 300
        self.url = 'imageurl'
      end
    end
  end
  self.right_panel = build_panel do
    self.priority = 'normal'
    self.template_type = 'template'
    self.title = 'サンプルタイトル'
    add_link do
      self.id = 'right-sample1'
      self.title = 'right-title-sample1'
      self.url = '//www.example.com/'
      add_image do
        self.width = 200
        self.height = 300
        self.url = 'imageurl'
      end
    end
  end
end

ただここまで書くなら、

JSON.generate(
  id: '999'
  title: 'サンプルタイトル'
  url: '//www.example.com/'
(略)
)

と書けばいいのでは?と思い、.build doの書き方ができるようになるとどういったことで意味があるのか質問したところ、

コードの見た目から把握できる情報が少ないということを伝えたかったです。
例えばLinkはImageをlistとして持っているのですが、
今のコードだとLinkもImageも並べて作っているので、パッと見たときに構造化されていると気づきづらいです。
builderにすることで、構造的な情報を含められるのが嬉しい点です。ってのを伝えたかったです。
後は毎回書いているApiを不要にできるのですっきりします。
その上で、JSON.generateとの比較点があるとすれば、attribute間違いなどのケアレスミスを防げると思います。
今は実装されていないですが、例えばvalidationを実装しておけば、そういった利点にも繋がるという感じです。
この辺りは最初のころに話したHash#to_jsonより便利じゃないとっていう話に繋がるところです。

という納得のいく説明をもらったので、実装に向けて色々調べないといけないが、まだまだ指摘されている実装を実現するまでの道のりは遠そうだ…。