Що таке область застосування / named_scope в рейках?


105

Я нещодавно почав стажування. Мій роботодавець використовує рубіни на рейках, і я часто зустрічаю нові синтаксиси, які мені потрібно шукати, щоб зрозуміти. Я гуглився навколо для того, щоб добре пояснити im_scope, але те, що я знайшов до цього часу, - це переважно повідомлення в блогах, що дають високу оцінку за це, скоріше прямого визначення або вступу.

Що саме має ім'я_scope (тепер його просто називають сферою дії) в рубіні на рейках?



2
Ця публікація в блозі була для мене неоціненною, коли я вивчав сфери з назвою: ryandaigle.com/articles/2008/8/20/…
Пітер Браун

@notapatch посилання мертве у вас є ще одне?
mbigras

Ryan Daigle: Названий обсяг: це не просто для умов, Ya Know ?: web.archive.org/web/20160306110506/http://…
notapatch

Відповіді:


212

Область - це підмножина колекції. Звучить складно? Це не так. Уявіть собі це:

У вас є користувачі. Зараз деякі з цих користувачів підписані на вашу розсилку. Ви позначили тих, хто отримує інформаційний бюлетень, додавши поле до Бази даних користувачів (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


7
Чи можу я запитати, у чому переваги цього, ніж сказати, визначаючи метод у класі користувачів під назвою "передплачені користувачі"? напр. 'def self.subscribeServes self.where (: передплачений_to_newsletter => вірно) кінець
redroot

3
@redroot перевага в тому, що scopeсинтаксис набагато чистіший, ви отримуєте той самий результат, але лише за допомогою одного рядка
Aldo 'xoen' Giambelluca

9
@redroot Раніше була велика перевага в ефективності, оскільки сфери ліниво запитували базу даних, тоді як методи роблять це нетерпляче. У Rails 3 методи також ліниві, тож тепер різниця синтаксичніша. Джерело
evanrmurphy

API посилання на документ перервано, будь ласка, оновіть api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/…
Lohith MV

Також дозволяє користуватися посиланням на
скопійовані

34

область в активному записі подібна до методів класу, але вони повертають об'єкт Relation, що означає, що ви можете викликати інший діапазон або активний метод запиту запису на ньому.

Наприклад, якщо у вас є модель Zombie (таблиця зомбі) із наведеними нижче способами застосування,

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

Приклад вище ґрунтується на синтаксисі рейки 4


Я не можу знайти приклад замовлення (: created_at,: desc) в жодній документації. Чи можливо це ви мали на увазі scope :recent, -> { order(created_at: :desc) }? apidock.com/rails/v4.2.9/ActiveRecord/QueryMethods/order
notapatch


7

Області застосування - це не що інше, як класичні методи.

Навіщо їх використовувати?

Оцінка масштабу дозволяє вказати часто використовувані запити (це може розглядатися як ярлик для довгих або найбільш часто використовуваних запитів), на які можна посилатися як виклики методів для об'єктів або моделей асоціації. За допомогою цих областей ви можете використовувати кожен раніше розглянутий метод, наприклад, де, приєднується та включає. Усі методи діапазону повернуть об’єкт ActiveRecord :: Relation, який дозволить викликати в ньому подальші методи (наприклад, інші області).

Щоб визначити просту область, ми використовуємо метод області всередині класу, передаючи запит, який ми хотіли б запустити, коли ця область називається:

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


3
Це не зовсім те саме, що визначення методу класу . Класові методи повертаються nilв декількох випадках, і тому не підлягають певним умовам.
Арслан Алі

1
  • Уявіть, у вас є модель: 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.

Тепер це було не так важко?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.