私は最近インターンシップを始めました。私の雇用主はRuby on Railsを使用しており、理解するために調べる必要のある新しい構文に頻繁に遭遇します。これは、ほとんどの場合、それを高く評価するブログ投稿であり、むしろ単純な定義または紹介です。
Ruby on railsのnamed_scope(現在、単にスコープと呼ばれています)とは何ですか?
スコープはコレクションのサブセットです。複雑に聞こえますか?そうではありません。これを想像してください:
ユーザーがいます。現在、これらのユーザーの一部はニュースレターを購読しています。ユーザーデータベースにフィールドを追加して、ニュースレターを受信するユーザーをマークしました(user.subscribed_to_newsletter = true)。当然、ニュースレターを購読しているユーザーを取得したい場合があります。
もちろん、常にこれを行うことができます:
User.where(subscribed_to_newsletter: true).each do #something
しかし、常にこれを書く代わりに、このようなことをすることができます。
#File: users.rb
class User < ActiveRecord::Base
scope :newsletter, where(subscribed_to_newsletter: true)
#yada yada
end
Rails 4以降を使用している場合は、代わりにこれを行います:
#File: users.rb
class User < ActiveRecord::Base
scope :newsletter, -> { where(subscribed_to_newsletter: true) }
#yada yada
end
これにより、次の操作を行うだけでサブスクライバーにアクセスできます。
User.newsletter.each do #something
これは非常に単純な例ですが、一般的なスコープでは作業を簡単にするための非常に強力なツールになります。
このリンクを確認してください: API Description
アクティブレコード内のスコープはクラスメソッドに似ていますが、リレーションオブジェクトを返します。つまり、別のスコープまたはアクティブレコードクエリメソッドを呼び出すことができます。
たとえば、下記のスコープメソッドを持つゾンビモデル(ゾンビテーブル)がある場合、
class Zombie
scope :rotting, -> { where(rotting: true) }
scope :fresh, -> { where('age < ?', 25) }
scope :recent, -> { order(:created_at, :desc) }
end
そしてあなたは電話する
Zombie.rotting.fresh.recent.limit(3)
SQLでは次のように変換されます。
select "zombies.*" from "zombies" where "zombies"."rotting" = 't' and (age<20) order by create_at desc limit 3
上記の例は、Rails 4構文に基づいています
スコープはクラスメソッドに他なりません。
なぜそれらを使用するのですか?
スコーピングにより、メソッド呼び出しとして参照できる一般的に使用されるクエリ(長いクエリまたは最も頻繁に使用されるクエリのショートカットと見なすことができます)を指定できます関連オブジェクトまたはモデル上。これらのスコープを使用すると、where、join、includeなど、以前に説明したすべてのメソッドを使用できます。すべてのスコープメソッドは、ActiveRecord :: Relationオブジェクトを返します。これにより、他のメソッド(他のスコープなど)を呼び出すことができます。
単純なスコープを定義するには、クラス内でscopeメソッドを使用し、このスコープが呼び出されたときに実行するクエリを渡します。
class Article < ActiveRecord::Base
scope :published, -> { where(published: true) }
end
これはクラスメソッドの定義とまったく同じであり、使用するのは個人的な好みの問題です。
class Article < ActiveRecord::Base
def self.published
where(published: true)
end
end
例の詳細な説明については、次のリンクを参照してください。これがお役に立てば幸いです。
今あなたを想像してください:
スコープを使用して、特定のクラスの人々を取得できます!
Person.red_hair.cricket ## finds all people with red hair who play cricket
Person.red_hair ## finds all people with red hair
Person.cricket ## finds all people who play cricket.
さて、それはそれほど難しくありませんでしたか?