Рейки. Де проти. Знайти


76

Я помітив, що Model.whereметод завжди повертає масив, навіть якщо є лише один результат, де як Model.findметод цього не робить. Чи є для цього якась причина? Я вважав, що Model.whereце найкраща функція, оскільки Rails 3.X.

Чи повинен я використовувати, Model.findколи я очікую одного результату і Model.whereколи я очікую більше одного результату?

Відповіді:


120
  • whereповертає ActiveRecord::Relation(не масив, хоча він поводиться приблизно так само), який є колекцією об'єктів моделі. Якщо ніщо не відповідає умовам, це просто повертає порожнє відношення.

  • find(та пов’язані з ним динамічні find_by_columnnameметоди) повертає один об’єкт моделі. Якщо нічого не знайдено, виникає ActiveRecord::RecordNotFoundвиняток (але не з динамічними find_by_методами).

    Хоча findможе повернути масив записів, а не відношення, якщо йому надано список ідентифікаторів, використання whereє переважним, оскільки Rails 3. Багато подібних застосувань findтепер застаріли або повністю припинено .

Так що так, якщо ви хочете і очікуєте лише одного об’єкта, користуватися ним findпростіше, оскільки в іншому випадку ви повинні телефонувати Model.where.first.

Зверніть увагу, що параметри хешу старого стилю findта багато динамічних find_методів застаріли станом на Rails 4.0 ( див. Відповідні примітки до випуску ).


я думаю, що findможе повернути кілька об'єктів у масиві - спробуйте User.find [1,2,3](знаходить користувачів з ідентифікаторами 1, 2 та 3) ... але так, я здогадуюсь andrew має рацію щодо решти
klump

3
@klump Так, може, але User.where(id: [1, 2, 3])в цьому випадку є кращим, тому я навіть не розглядав це. Як завжди, я рекомендую прочитати документацію щодо API (на яку я посилався у своїй відповіді), оскільки вона містить найбільш детальну інформацію.
Ендрю Маршалл

Але .find(:all, ...)повертає масив. То яка різниця між знахідкою та де?
highBandWidth

@highBandWidth Див. коментарі вище. Я також оновив свою відповідь. whereне повертає масив (хоча Model.where(...).classбрехатиме і скаже, що є).
Ендрю Маршалл,

13

Фактично find_byбере об'єкт моделі з whereотриманогоActiveRecord::Relation

def find_by(*args)
  where(*args).take
end

Джерело


4
Зверніть увагу, що find_by було додано лише до Rails 4 (оригінальне запитання було позначене рейками 3).
Стів

6

Model.findвикористовує стовпець первинного ключа. Тому результат завжди є рівно один або його немає. Використовуйте його, коли ви шукаєте певний елемент, ідентифікований його ідентифікатором.


7
Ні, якщо ти це робиш .find(:conditions => {:col_name => some_vals}).
highBandWidth
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.