LoginSignup
1
1

More than 1 year has passed since last update.

ActiveSupport::Concernを簡単に解説!

Last updated at Posted at 2021-05-17

Consernとは何か

モデルやコントローラーの処理において、共通している処理を別ファイルにまとめることでDRYなコードを書くことが出来るものです。
これにより効果的なリファクタリングが可能です!

基本的な使い方

以下のようなモデルがあるとします。
同じ処理をしているので、こういった処理に対してActiveSupport::Concernを利用してリファクタリングを行う。

app/models/user.rb
...
scope :foo, -> {puts 'foo'}
scope :bar, -> {puts 'bar'}
...
app/models/post.rb
...
scope :foo, -> {puts 'foo'}
scope :bar, -> {puts 'bar'}
...

sample_concern.rbのようなファイルを作成し、共通した処理を記述する。

app/models/concerns/sample_concern.rb
module Sample
  extend ActiveSupport::Concern

  included do
    scope :foo, -> {puts 'foo'}
    scope :bar, -> {puts 'bar'}
  end
end

そうすると、先程のuser.rbとpost.rbは以下のように簡単に書けます。

app/models/user.rb
class User < ApplicationRecord
  include Sample
...
app/models/post.rb
class Post < ApplicationRecord
  include Sample
...

注意点

ビジネスロジックはモデルに書く

コントローラーに定義されたメソッドを、Concernsにしてリファクタリングしようとした際に、このメソッドがビジネスロジックの場合、良くないとされています。
ビジネスロジックがコントローラ、モデルの両方に存在していると、特定の処理を追いかける際に、色んな場所に探しにいく事になるので、コードの見通しが悪くなります。

rubocopのClassLength対策としてConcernsは利用しない

Concernsを利用すると、クラス自体の長さを短くすることが出来て、一見綺麗に見えます。
しかし、rubocopのClassLength警告は「該当クラスが責務を持ちすぎである」ということの指摘なので、実質的な責務を減らさないConcernsは意味がありません。
コードも追いづらくなるので可読性を下げる事になります。

複雑なビジネスロジックをConcernsにする

includeで手軽にメソッドを増やせるのと、コンテキストを分けることで実装をリファクタリングしやすくなる

終わりに

リファクタリングをすることでコードを綺麗にする事が出来るので、良いですよね。
しかし、クラスから単純にConcernsに切り出しても責務が減る事は無いので、責務を減らしたいのであればクラスとして切り出したほうが良いっぽいです。。
最初からConcernsとして切り出そうとするのではなく、まず別の方法も検討してみましょう!

参考

我々はConcernsとどう向き合うか

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1