Railsアプリに秩序をもたらすGem、Trailblazerとは？

ここ1年で、Trailblazerの認知度は急速に上がってますよね。
[BestGemsで見てみる](http://bestgems.org/gems/trailblazer)とここ1年でめっちゃ伸びてます。
![スクリーンショット 2017-09-14 18.16.31.png](https://qiita-image-store.s3.amazonaws.com/0/42541/eab436ea-0c23-7690-fead-fb959d526345.png "スクリーンショット 2017-09-14 18.16.31.png")
1月時点で6万4千DLだったのが、9月現在で既に15万を突破しているので、今年だけで倍以上のダウンロードですね…！
今回はそんな要チェックなGem、Trailblazerについて簡単に見ていきたいと思います。

# Trailblazerとは
Trailblazerは、RailsやSinatraなどで綺麗にビジネスロジックを書くためのGemです。
ModelやControllerが肥大化してカオスになっているアプリケーションに秩序をもたらしてくれます。

…なのですが、「具体的に何をするGemなの？？？」ってことですよね。
Trailblazerは複数のGemから構成されています。今回は代表的なGemである **Operation** 、 **Reform** 、 **Cells**、 **Representable** を見ていきたいと思います。

# Operation
まずはOperationですね！ いわゆるサービスクラスを作るためのGemです。
ControllerやModelなどから複雑なビジネスロジックを切り離し、サービスクラスとして記述できるようになります。
特徴的なのは、強力な処理フローの制御。ぐっちゃぐちゃなネストの深いControllerのアクションとは強制的におさらばさせられます。[^1]
また、サービスクラスを記述する上での細かいマクロ群もあり、なかなか使いやすいと思います。

[^1]: 次期バージョンの2.1では、さらに柔軟な制御ができるようになります！ こうしたアップデートもTrailblazerの魅力です。


```ruby
class User::Create < Trailblazer::Operation
  step Model(User, :new)
  step Contract::Build(constant: MyContract) # Formオブジェクトをビルド
  step Contract::Validate() # validationする
  step Contract::Persist() # modelにデータを反映して保存する
end
```

# Reform
Reformは、いわゆるフォームオブジェクトを作るためのGemです。
Modelなどからフォームに関連する処理を切り離してくれます。

例えば、バリデーションであったり（Reformを使うとModelではなくフォームオブジェクトでバリデーションします）、`accepts_nested_attributes_for`のような複数のModelをフォームで表現するための処理などを書きます。
Modelの前にフォームオブジェクトが入ってくれるので、「ユーザ登録画面は利用規約のチェックが必要なんだけど、このバリデーションをUserモデルに書くのってどうなんだろう？ :cold_sweat:」という悩みからも解放されますね！

```ruby
module User::Contract
  class Create < Reform::Form
    property :name, validates: { presence: true, length: { maximum: 50 } }
    property :password, validates: { presence: true, length: { minimum: 16 }
  end
end
```

# Cells
Cellsは、いわゆるビューモデルを作るためのGemです。Modelなどから表示用のメソッドなどを切り離せます。
例えば、ユーザの状態を`status`というpropetyに **数値** で入っている場合に、`"有効"`と`"無効"`という **文字列** で表現したい場合、その変換コードをCellに書きます。

「そんなのModelに書かずにHelperに書くよ」という方も多くいらっしゃるでしょう。
Cellの良い点は、Helperと違ってインスタンス化されたオブジェクトだという点です。一般的なRubyのオブジェクト指向としての利点、つまり「継承」「カプセル化」「ポリモーフィズム」などを扱えるようになります。
例えば、Cellsのクラスと特定のViewをセットにして自由に閉じた空間に置けるので、大きな空間を汚さない安心感[^2]や可読性が得られると思います。

[^2]: Helperがmix-inされる時のメソッド衝突の恐怖を経験した方もいるでしょう :scream: 

```ruby
class BookCell < Cell::ViewModel
  property :author

  def show
    render
  end

private
  def author_link
    link_to "#{author.email}", author
  end
end
```

# Representable
Representableは、ObjectをJSONやYAML、XMLに変換するためのGemです。[^3] 逆にJSONからObjectに変換する機能もあります。
JSONを返すAPIを作る時にはModelの情報をJSON変換すると思いますが、`to_json`だけでは済まないこともしばしばありますよね。カラムとしては存在しないプロパティを出力するためにModelにメソッドを作ったり、数値を文字に変換する必要があったり。
そうした処理をModelに書くと肥大化していきますが、Representableを使えば切り離すことができます。

[^3]: いわゆるシリアライザー…なのかもしれませんが、シリアライザーというワードで思い浮かべるものに（世間的に）幅があるような気がします :thinking: 

```ruby
class UserRepresenter < Representable::Decorator
  property :id
  property :name, exec_context: :decorator

  def name
    "#{represented.first_name} #{represented.last_name}"
  end
end
```

ちなみに、ほかの用途としてAPIの仕様書やモックを作る時などにも使用できます。
RoarというGemがTrailblazerにありますが、こちらはRepresentableを内部的に使ってAPIのレスポンスをレンダーしたりパースしたりできます。
APIのクライアントも作れるGemなので、マイクロサービスを作ろうとしている方にはRoarも便利かもしれません（使ったことはないです :sweat_smile: ）。

# おわりに
Trailblazerはカバーする範囲が広いので「これをやるGemです！」となかなか言いづらいのですが、あえて言うなら「RailsのコードががスッキリするGem」という感じでしょうか。

Trailblazerでは今回紹介したGem以外にも様々なGemが使えますが、全てを使う必要はありません。
弊社では、JSONの変換ロジックをControllerやModelに書きたくないという課題感でRepresentableから使い始めて、しばらくしてOperationとReformを導入し、いまCellsを導入しているところです。
その間、普通に過去のコードも動いているので、じわじわと移行しています。特殊なテクニックを使わなくても、Trailblazer化していないコードと共存できる点は素晴らしいですね。

1つずつ使っても十分メリットありますので、皆さんも興味のある機能から使い始めてみてはいかがでしょうか。

# 参考
最近頑張って入門記事も書いたので（弊社メンバーと若干被りました :sweat_smile: ）、実際に使ってみたいな、という方は以下リンクから是非。
Trailblazerは日本語記事がとても少ないので、ちょっとずつでも増やしていきたい所存です :+1: 

[Trailblazerを使い、Railsのモデルの肥大化問題からサヨナラする](http://qiita.com/kouheiszk/items/c8a2b50529f7a0842c71) : 
OperationとReformのもう少し詳しい内容がまとまってます

[Railsでサービスクラスとフォームオブジェクトを使ってサッと良い感じにする](http://qiita.com/kazekyo/items/eb679d2ed8b05bb695be) : 
Railsチュートリアルのコードを使用して、実際にOperationとReformの導入を行います