Что такое scope/named_scope в рельсах?

Недавно я начал стажировку. Мой работодатель использует рубины на рельсах, и я часто сталкиваюсь с новым синтаксисом, который мне нужно найти, чтобы понять. Я искал googled для хорошего объяснения named_scope, но то, что я нашел до сих пор, - это в основном сообщения в блогах, дающие высокую оценку за это, а не просто определение или введение.

Что такое named_scope (теперь просто называемый scope) в ruby ​​on rails?

Ответ 1

Сфера - это подмножество коллекции. Звучит сложно? Это не так. Представьте себе следующее:

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

Ответ 2

Область действия в активной записи похожа на методы класса, но они возвращают объект Relation, что означает, что вы можете вызвать для него другую область действия или метод запроса активной записи.

Например, если у вас есть модель зомби (таблица зомби) с нижеприведенными методами области действия,

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

Ответ 3

Лучший способ понять подробности - перейти к документации по API.

Вы получите полную информацию и способы использования Scopes.

Документация по API-интерфейсу API

Ответ 4

Области действия - не что иное, как методы класса.

Зачем их использовать?

Область действия позволяет указывать часто используемые запросы (это можно рассматривать как ярлык для длинных или наиболее часто используемых запросов), на которые можно ссылаться как вызовы методов для объектов или моделей ассоциации. С этими областями вы можете использовать каждый ранее описанный метод, например, где, объединяет и включает. Все методы области будут возвращать объект 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

Ответ 5

  • Представьте, что у вас есть модель: человек.

Теперь представьте себя:

  • хочу всех людей в мире, у которых рыжие волосы.
  • хочу, чтобы все люди в мире, которые играют в крикет

Вы можете получить эти конкретные классы людей, используя прицел!

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.

Теперь это было не так сложно, не так ли?