Help us understand the problem. What is going on with this article?

TrailBlazer概要まとめてみた

TrailBlazerを使う機会がありました。
日本語のリソースが少なかったので、軽くではありますがまとめておこうと思います。
まだ理解が若干ふわふわしているので、誤りなどあればご指摘いただけると幸いです!

Trailblazerとは?

Rubyのフレームワークに抽象レイヤーを提供するGemの集まりです。
(Railsのほか、HanamiやGrape, Sinatram等にも対応。また「TrailBlazer的設計スタイル」という意味では、どんな言語やフレームワークにも適用可能)

そもそものはじまりは、作者のNick Sutterer氏がRailsのMVC抽象レイヤーのあり方に疑問を持ったこと。Railsの手軽さを認める一方、ModelやControllerの肥大カオス化により、のちの保守性が下がることを問題視されたそうです(Nickさんの本意訳)。

Railsの設計思想の特徴ゆえに、迷子になりがちだったビジネスロジックの行き場をModelやController以外の場所に持ってくることができます。

Trailblazerを構成する主なGem

TrailBlazerは、Operation・Reform・Cells・Representableという主に4つのGemから構成されています。
Nickさん自身も述べていらっしゃいますが、すべてのGemを用いる必要はありません。
むしろ、「いつ」「どれくらい」「どの」要素を用いたいかに基づいて、部分的に各Gemを導入できるため、比較的容易に既存アプリケーションと併用することができます。

Operation

コントローラーに代わってビジネスロジックを担当するGemです。
stepによる簡潔な処理フローを強みとしています。

app/concepts/dinosaur/operation/create.rb
class Dinosaur::Create < TrailBlazer::Operation
  step Model( Dinosaur, :new )

  # あとで登場するFormオブジェクトをビルド
  step Contract::Build( constant: Dinosaur::Contract::Create )

  # ビルドしたFormオブジェクトをValidation
  step Contract::Validate()

  # ValidationしたFormオブジェクトをModelに反映
  step Contract::Persist()

end

TrailBlazerにおけるModelの役割は、RailsのModelの役割と基本的に同じです。
Controllerから指示を受けてデータのやり取りを行うか、Operationからの指示を受けるかというほどの違いで、永続化したいデータをDBに保存したり、その値を取得するポータルを提供することがメインのお仕事です。
以下のように、associationやscopeを記載します。

app/models/dinosaur.rb
class Dinosaur < ActiveRecord::Base
  belongs_to :ancient_creatures
  has_many :types

  scope :name, ->(name) { where(name: name) }
end

上記の例ではRailsのActiveRecordを使用していますが、Datamapperなど、ほかのORMでも問題ありません。
*ORM:Object Relational Mapping(オブジェクト関係マッピング)のこと。オブジェクト指向と関係データベースをつなぐことで、関係DBのレコードをオブジェクトとして認識し、直感的な操作を可能にしてくれる。

Reform

フォームオブジェクトを作るためのGemです。
ValidationやPersisting(savesync)をメインに、フォーム関連の処理をModelに代わって引き受けます。
contractは、Reform::Fromクラスを継承しており、必要項目のpropertyvalidates内容の定義を行う役割を持ちます。

app/concepts/dinosaur/contract/create.rb
module Dinosaur::Contract
  class Create < Reform::Form
    property :name
    validates :name, presence: true

    property :type do
      property :color 

      validates :color, presence: true
    end
  end
end

上記のバリデーションにはRailsのActiveModelを使用していますが、TrailBlazer v2.0以降であれば、dry-validationなども選択可能です。ただ、ActiveModelに関しては将来的に廃止を予定しているとのことです。

Cells

ビューモデル作成用のGemです。
表示関連の処理をModelに代わって引き受け、UIパーツを表現します。
別名「テンプレート・レンダリング」担当。

app/concepts/comment_cell.rb
class CommentCell < Cell::ViewModel
  def show
    render # app/concepts/comment/show.hamlをレンダリングする
  end
end

Representable

シリアライズ(デシリアライズ)用のGemです。
受け取ったオブジェクトをJSONやXML、YAMLに変換するほか、JSONからオブジェクトへの変換も可能です。
Operationの中に記述するほか、別ファイルに専用クラスを定義する方法があります。
例として、以下のようなオブジェクトをフォームから受け取るためには、

{
  "name" => "Velociraptor",
  "color"  => "Blue"
}

(方法1) Operationファイル内に記述する

app/concepts/dinosaur/operation/create.rb
class Dinosaur::Create < TrailBlazer::Operation
  ...
  representer do
    property :name
    property :color
  end
end

(方法2) 別ファイルにクラスを定義する(下記の例ではDinasourRepresenter

app/concepts/dinosaur/representer/dinasour_representer.rb
class DinasourRepresenter < Representable::Decorator
  include Representable::Hash # 受け取りたいオブジェクトのフォーマット
  include Representable::JSON # レスポンスとして返したいフォーマット

  property :name
  property :color
end

JSON形式でレスポンスを返すためには、

DinasourRepresenter.new(dinasour).to_json

おつかれさまでした!

お付き合いくださり、ありがとうございました!
今年も残り少し、よろしくおねがいします!

参考文献

TrailBlazer作者Nickさんの本
TrailBlazer Github
TrailBlazer Official
TrailBlazer Operation

以下のQiita記事を参考にさせていただきました!ありがとうございました!
@kazekyoさま
@kouheiszkさま
@yk-nakamuraさま

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした