concernの使い方調べてみた
Daily Blogging99日目
RailsにおいてFatなModelに対してどう対応するかは良くある悩みであり、組織によって対応はいろいろ異なる。
そのうちの1例がconcernを使うこと
自社でもconcernは使われているが、昔からあるconcernを利用しているだけで
実際どういう概念なのか、どう使うべきなのかはあんまりよく知らない
concernはアンチパターン?
ネットで調べようとすると、検索候補でアンチパターンが出てくる
「concernはうちではこう使ってます。」みたいな記事も多く見かけるので、みんなconcernの扱いには結構困っていそう。
concernの使い方
Jorge Manrubiaさんによると、
concernはよく「可読性を下げるものである」という批判を受けているそう。
でも実際にはその逆で、concernは適切に使えば可読性を向上させるものになるらしい。
複雑さの管理をしやすくしてくれる
The essence of dealing with complex systems is to divide them into smaller pieces over and over so we can focus on one thing at a time.
(訳)
複雑なシステムを扱う上で重要なのは、それを小さな単位に分割し、一度に一つのことに集中できるようにすることです。
concernはそのために活用できるものであり、それをうまく活用するために重要なのは
元のモデルが持つ特徴(機能)をまとめること
例えばこんな感じ
class User < ApplicationRecord
include Reviewer
end
module User::Reviewer
extend ActiveSupport::Concern
included do
# Userが書いたレビューを管理
has_many :reviews, foreign_key: "author_id", class_name: "Review", dependent: :destroy
end
# レビューを投稿するメソッド
def write_review(product, content)
reviews.create(product: product, content: content)
end
# 特定の製品についてレビューしたかどうかをチェックするメソッド
def reviewed?(product)
reviews.exists?(product: product)
end
end
この例では、「ユーザのレビュアーとしての振る舞い」をconcernに抽出している。
これで、レビュアー機能についてはconcernを見れば全部把握できる。
→一つのことに集中できる
モデルが持つ機能、概念を抽象化してくれる
class Topic < ApplicationRecord
include Accessible, Breakoutable, Deletable, Entries, Incineratable, Indexed, Involvable, Journal, Mergeable, Named, Nettable, Notifiable, Postable, Publishable, Preapproved, Collectionable, Recycled, Redeliverable, Replyable, Restorable, Sortable, Spam, Spanning
.
.
.
includeの部分を見るだけで、Topicクラスが持つ機能、概念が一目でわかる
※まぁこの例だとちょっと多すぎる気もするけど
Discussion