はじめに
Railsのscope機能は、共通的に使うクエリーをメソッドのように定義することができる便利な機能です。ですが、システムが肥大化するにつれ、モデルクラス内がscopeを宣言しすぎると、見通しが悪くなってしまいます。そこでscopeをActiveSupport::Conernに分割する方法をまとめます。
実行環境
- Ruby 2.4.0
- Rails 5.0.1
ActiveSupport::Concern とは
Railsで共通処理をモジュールとして切り出し、インクルードすることでモジュールを使用することができます。詳しくはこちらをご覧ください。
ActiveSupport::Concernでscopeを分割する
以下のUserモデルには4つのscopeが宣言されています。
app/models/user.rb
class User < ApplicationRecord
scope :trial, -> { where(state: 'trial') }
scope :active, -> { where(state: 'active') }
scope :inactive, -> { where(state: 'inactive') }
scope :canceled, -> { where(state: 'canceled') }
end
モデルにActiveSupport::Concernを導入するには以下の手順で行います。
-
app/models/concerns/
以下のモジュールファイルを作成する -
ActiveSupport::Concern
モジュールをextendで取り込む - includedブロック内でscopeを宣言する
- モデル側でモジュールをincludeする
これでCorcernにファイル分割することができ、ソースコードがすっきりします。
app/models/concerns/sample.rb
require 'active_support'
module Sample
extend ActiveSupport::Concern
included do
scope :trial, -> { where(state: 'trial') }
scope :active, -> { where(state: 'active') }
scope :inactive, -> { where(state: 'inactive') }
scope :canceled, -> { where(state: 'canceled') }
end
end
app/models/user.rb
class User < ApplicationRecord
include Sample
end