2014-10-28 3 views
0

Из того, что я прочитал с помощью области в Rails, более эффективно, так как ваш запрос модели напрямую в отличие от переменной экземпляра, которая проходит через контроллер к модели (как я ее вижу?)Сфера или переменная экземпляра

Так у меня есть этот запрос в мой контроллер

@animal_location = User.select(:town).map(&:town).uniq 
["Cardiff", "Newport"] 

, а затем эта сфера в моей модели

scope :uniq_towns, ->() { 
select("town").group("town") 
} 
#<ActiveRecord::Relation [#<User id: nil, town: "Cardiff">, #<User id: nil, town: "Newport">]> 

на мой взгляд, чтобы получить доступ к значению города, используя @animal_location = User.select(:town).map(&:town).uniq Я могу получить доступ как

<% @animal_location.each do |loc| %> 
    <%= loc %> 
<% end %> 

или если я использовал сферу и пошел с @animal_location = User.uniq_towns, на мой взгляд, я хотел бы использовать

<% @animal_location.each do |loc| %> 
    <%= loc.town %> 
<% end %> 

Мой первый вопрос будет мой сфера будет быстрее в этом случае и во-вторых моя сфера правильно, как я получаю идентификатор пользователя: ноль как часть хэша

Спасибо

+1

Я не думаю, что запросы с областью более эффективны, чем обычные запросы. Они просто требуют меньше ввода для вызова, когда это необходимо. – zwippie

ответ

2

это зависит от того, что ваш источник означает «эффективный». Области предназначены для сохранения кода DRY в смысле «Не повторяйте себя» и реализации шаблона рефакторинга «метод извлечения» для запросов ActiveRecord (AR). Они просты в обслуживании.

Зачем использовать его? Если вы используете один и тот же запрос в нескольких местах, рассмотрите ситуацию, когда вам нужно изменить его везде. Вы должны найти & заменить все вхождения. Этот способ подвержен ошибкам и вызывает больше различий в управлении версиями, которые сложнее отслеживать.

Извлечение этого запроса в метод кажется логичным решением. Класс метод?No, maybe you shouldn't, но просто положить области только. С помощью областей вы:

  • Получить единое место для построения запроса с определенным значением (и использовать его по всему приложению)
  • Будьте уверены, что результат сферы является цепным, так как в результате является допустимым отношением AR (и вы можете применять его в верхней части)
  • Укажите значение вашего запроса - хорошее читаемое имя, чтобы сохранить читаемый код контроллера (с использованием областей видимости в действии, но с помощью MVC, которые следует использовать Rails)

У вас есть:

@animal_location = User.select(:town).map(&:town).uniq 

Прежде всего, я не понимаю, почему map и group необходимы, это работает отлично слишком и использует SQL DISTINCT:

@animal_location = User.select(:town).uniq 

Это выглядит достаточно shourt, чтобы быть читаемыми. Но давайте продемонстрируем области здесь. В вашей типовой проблеме это:

scope :uniq_towns, ->() { 
select("town").uniq 
} 

...так что вы можете написать это в вашем контроллере:

@animal_location = User.uniq_towns 

Есть и другие пути решения этой ситуации, как before_filter, но это выходит за рамки вопроса.

+0

Благодарим вас за подробный ответ, конечно, для меня очистка. – Richlewis