RailsのScopeの隠れた仕様

最近、Railsを勉強している中で初めて知って驚いたScopeの仕様を紹介します

Railsを使いこなしている方なら常識なのかもしれませんが

私は知らなかった...

Scopeの隠れた仕様!

私が驚いたScopeの仕様

それはなんと、Scopeの条件に一致しない場合は、allメソッドで返してくれるということ!

Railsの公式には、

条件文を評価した結果がfalseになった場合であっても、スコープは常にActiveRecord::Relationオブジェクトを返します。クラスメソッドの場合はnilを返すので、この点において振る舞いが異なります。

とは書いてありましたが、allメソッドで返してくれるとは知りませんでした

railsguides.jp

Scopeの基礎的な使い方

ちなみに、Scopeについて簡単に説明すると

Modelによく使うクエリを名前をつけて定義しておくことができます

これがscopeというものです

これによって、同じ条件のクエリをこのScopeを使うことで修正しやすくなったり、

Controller側が膨らみすぎることを防いだりできます

先ほどのRailsガイドの例を参考にすると、以下のように書くことでScopeを宣言できます

class Article < ApplicationRecord
  scope :published, -> { where(published: true) }
end

以下の記事が基礎から詳しく書いてあり分かりやすかったです!

pikawaka.com

個人的に思ったscopeの注意点

Scopeを使わないで普通にwhereなどを使った場合、見つからないときは空のActiveRecord::Relationが返ってきます

しかし、Scoopの場合はActiveRecord::Relationという点は同じですがallメソッドが働いて全データを取ってきます

このことが頭に入っていれば問題ないですが、結果が違うのでどっちを使っているをしっかりと理解して使うことが大事だということです

また、見つけた記事ですがモデルの外でチェインするのもテストやメンテナンス性が低くなるため、できるだけモデル内であらかじめチェインしておいてControllerなどで使うと良いそうです↓

techracho.bpsinc.jp

最後に

私自身最近知ったことなのと、元々Scopeを使いこなせてはいなかったのでにわかですが、

今後使えるところでどんどん使ってより良いコードを書いていきたいなと思った次第です!