2012-06-27 2 views
25

У меня есть следующий код:Rails "find_all_by" против ".гда"

def maturities 
    InfoItem.find_all_by_work_order(self.work_order).map(&:maturity) 
end 

Я думал об изменении его:

def maturities 
    InfoItem.where(work_order: self.work_order).map(&:maturity) 
end 

Будет ли какое-то преимущество в этом? Похоже, .where чаще встречается, чем find_all_by.

+0

Я нахожусь в процессе обновления приложения из Rails 4.0.3 в 4.1.0 и мой код, который используется ' find_all_by' больше не работает ('NoMethodError'). Я ничего не вижу в примечаниях к выпуску, которые повлияют на него. Мне нужно переключиться на «где». Если бы я использовал 'where' с самого начала, мой код был бы менее подвержен таким ошибкам. Есть [комментарий ниже] (http://stackoverflow.com/questions/11232971/rails-find-all-by-vs-where#comment14759921_11233522), в котором упоминается, что 'find_all_by_ *' будет устаревшим в Rails 4. Тем не менее, это произошло как сюрприз для меня. Где документируется удаление этого метода? – Dennis

+0

Я нашел, где это задокументировано. В примечаниях к версии 4.1: «Убрана функция activerecord-deprecated_finders как зависимость. Для получения дополнительной информации см. Драгоценный камень README». – Dennis

+0

Я бы также предложил использовать 'pluck' вместо' map' в этом типе ситуации. 'InfoItem.where (work_order: self.work_order) .pluck (: maturity)' – jurassic

ответ

25

Мое мнение, что использование .where - лучший подход.

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

Кроме того, скручивание вместе: find_by_this_and_this_and_this_and_this ... может стать уродливым.

See how rails accomplishes attribute based finders here

Метод отсутствует модуля DynamicMatchers на GitHub:

def method_missing(name, *arguments, &block) 
    match = Method.match(self, name) 

    if match && match.valid? 
    match.define 
    send(name, *arguments, &block) 
    else 
    super 
    end 
end 
+2

Отличное объяснение – holaSenor

+0

Благодарим вас за то, что вы потратили время на размышления, я ценю ваш ответ. Я собираюсь позволить еще немного времени для других предложений, прежде чем отметить его как «мой ответ». Спасибо, сэр. – ardavis

+1

Добро пожаловать. Это только мое мнение и, возможно, не лучшее объяснение. Отличный вопрос! – Kyle

2

Я думаю, что основное преимущество заключается в том, чтобы добавить дополнительные критерии, где find_all_by ограничивается полем динамического селектора. Если у вас есть только одно условие, которое вы ищете, то я думаю, что это стирка, но когда вы начинаете добавлять 3 или 4, динамические искатели могут быть уродливыми. Хэши приятно смотреть, и вы можете передать хэш условий в качестве параметра, если это необходимо. Динамические искатели классные, но я думаю, что весы чище и читабельнее.

+0

Но я могу сделать что-то вроде: 'InfoItem.find_all_by_work_order_and_description (self.work_order,« bla bla bla »)' – ardavis

+0

Я не имею в виду, что вы не можете добавить больше к динамическому поисковому устройству, но передаете хэш как параметр, где он чище. IMO – holaSenor

+2

AFAIK. Где «Rails 3 way» делает это, не говоря уже о том, что он намного чище и гибче. –

Смежные вопросы