web-dev-qa-db-ja.com

Railsのscope / named_scopeとは何ですか?

私は最近インターンシップを始めました。私の雇用主はRuby on Railsを使用しており、理解するために調べる必要のある新しい構文に頻繁に遭遇します。これは、ほとんどの場合、それを高く評価するブログ投稿であり、むしろ単純な定義または紹介です。

Ruby on railsのnamed_scope(現在、単にスコープと呼ばれています)とは何ですか?

94
Ziggy

スコープはコレクションのサブセットです。複雑に聞こえますか?そうではありません。これを想像してください:

ユーザーがいます。現在、これらのユーザーの一部はニュースレターを購読しています。ユーザーデータベースにフィールドを追加して、ニュースレターを受信するユーザーをマークしました(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

190

アクティブレコード内のスコープはクラスメソッドに似ていますが、リレーションオブジェクトを返します。つまり、別のスコープまたはアクティブレコードクエリメソッドを呼び出すことができます。

たとえば、下記のスコープメソッドを持つゾンビモデル(ゾンビテーブル)がある場合、

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構文に基づいています

29
Akshatha

詳細について理解する最良の方法は、APIドキュメントにアクセスすることです。

完全な詳細とスコープの使用方法を取得します。

スコープのAPIドキュメント

7
123

スコープはクラスメソッドに他なりません。

なぜそれらを使用するのですか?

スコーピングにより、メソッド呼び出しとして参照できる一般的に使用されるクエリ(長いクエリまたは最も頻繁に使用されるクエリのショートカットと見なすことができます)を指定できます関連オブジェクトまたはモデル上。これらのスコープを使用すると、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

例の詳細な説明については、次のリンクを参照してください。これがお役に立てば幸いです。

http://guides.rubyonrails.org/active_record_querying.html

7
Imran
  • モデルがあると想像してください:Person

今あなたを想像してください:

  • 赤い髪を持っている世界中のすべての人々が欲しい。
  • クリケットをする世界中のすべての人々が欲しい

スコープを使用して、特定のクラスの人々を取得できます!

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.

さて、それはそれほど難しくありませんでしたか?

1
BKSpurgeon