Rails で ActiveInteraction を使うメリット


はじめに

ActiveInteraction とは、rails で controller に書かれるビジネスロジックを整理するときに使えるgemです。プロダクトが大きくなるにつれて複雑になり、太った controller や model をスリムにすることができます。また、ActiveModel が名詞でわかりやすく扱えるのと同様に、ActiveInteraction は動詞で命名してわかりやすく扱うことができます。

使いかたについては、ActiveInteraction の README または、こちらの Qiitaの記事 を参考にしてみてください。

この記事では、ActiveInteraction のメリットについて書いていきます。


ActiveInteraction を使うメリット


複雑になりがちな controller を簡潔にできる

ActiveInteraction を使う一番のメリットは、複雑になった controller を簡潔にできることです。

例 : order と report モデルがあり、二つは関連を持っているとします。report は、create した時にステータスによって通知を送るべきかどうか変えたい、という要件があった場合、そのロジックを controller から分離することができます。

(簡略化して書いています)

def create

# ここに書くべき内容を ActiveInteraction::Base を継承している create.rb に移動できる
outcome = Reports::Create.run(reports_create_params)

if outcome.valid?
redirect_to root_url, notice: 'create!'
else
flash.now[:alert] = 'error!'
render :new
end
end

# create.rb

module Reports
class Create < ActiveInteraction::Base
object :order, class: Order
object :account, class: Account
string :content, default: nil
array :images, default: []
string :to_state, default: nil

def execute
report = order.reports.build(
content: content, images: images,
account: account, date: Time.current.to_date
)

ActiveRecord::Base.transaction do
report.save!

unless to_state&.to_sym == :accepted
compose(Notifications::Send)
end
end

report
end
end
end

controller がとてもシンプルで読みやすいですね。

複雑な controller は可読性が悪く、バグを生む原因にもなります。

ActiveInteraction を使うことで、controller で書くことをシンプルに保つことができ、ビジネスロジックを名前空間を使って他のところに移動させることができます。

このメリットはservice層を作ることで補うこともできるのですが、ActiveInteraction を使うことでよりシンプルにわかりやすくなります。ちなみに僕の会社では、もともとservice層にロジックを押し込んでいたこともあり、今はservice層という名前空間に ActiveInteraction::Base を継承させて利用しています。

なぜ ActiveInteraction を使うとよりわかりやすくなるのか知りたい方は、こちらの記事をご覧ください。


バグを生みにくい(見つけやすい)

二つ目のメリットは、上記した通り、バグを生みにくいということです。

ActiveInteraction は静的型付けを行います。なので、型が原因で起こるバグを潰すことができます。型が決まっているので、複数人で開発している時でもその変数に何が入っているのか一目瞭然で可読性が高いです。

# このような感じでかけます

object :purchase, class: Order
object :account, class: Account
string :content, default: nil
array :images, default: []

また、Validation をつけることができます。書き方は model と全く同じです。そもそも ActiveInteraction 内で Validation チェックすることがあまりないので利用頻度は高くないと思いますが、こちらもうまく使うことでバグの原因を潰すことができます。


ロジックのテストが描きやすい

三つ目のメリットは、ロジックだけを隔離することにより、テストが描きやすくなることです。

ActiveInteraction は一つのロジックを一つのファイルに納めるので、テストが一つのロジック毎に別れ、シンプルに保つことができます。また、テストする部分を明確にすることができます。


最後に

ActiveInteraction は README がとてもわかりやすいので、困ったことがあれば大体は README で解決できます。