Почему поиск по одной записи возвращает массив? (Rails beginner)

#ruby-on-rails #ruby #ruby-on-rails-3 #ruby-on-rails-3.1

#ruby-on-rails #ruby #ruby-on-rails-3 #ruby-on-rails-3.1

Вопрос:

У меня есть операция where над моделью, которая возвращает один объект. Но, похоже, я не могу использовать его в объектной нотации (похоже, он возвращает массив с объектом в [0]).

 store = Store.where("some_id = ?", some_id)

puts store.name  # doesn't work

puts store  # shows array with the object at [0]
  

Ответ №1:

Потому что иногда вы не знаете, сколько объектов должен вернуть запрос, поэтому для согласованности вы всегда получаете массив.

Чтобы получить один объект, используйте

 store = Store.where("some_id = ?", some_id).first
  

Если вы ищете основной идентификатор модели, вы также можете использовать

 store = Store.find(some_id)
  

который вызовет исключение RecrodNotFound (по умолчанию обрабатываемое rails как 404), если он не найдет объект.

Комментарии:

1. как я мог проверить, не было ли возвращено результатов? похоже, это не работает: puts store.name unless store.blank

2. Он вернет, nil если ничего не было найдено, вы можете проверить с помощью store.nil? .

3. Последний глупый вопрос, Якуб… Есть ли лучшая нотация для записи .where("some_id = ?", some_id) … работает ли что-то подобное в rails… .where(:some_id => some_id)

4. Конечно, это так 🙂 На самом деле эти два должны работать одинаково. Также смотрите Мою правку к ответу.

Ответ №2:

Существуют также динамические средства поиска

 Store.find_by_some_id(some_id)
  

Они эквивалентны

 Store.where(:some_id => some_id).first
  

Комментарии:

1. Стоит отметить, что динамические средства поиска (отличные от find_by *) не поддерживаются в Rails 4 Источник: edgeguides.rubyonrails.org /…

Ответ №3:

Предложение Where в rails 3.x всегда будет возвращать объект arel, который вы можете использовать для цепочки методов.

Таким образом, оператор return предложения where всегда является массивом.

Для доступа к первому элементу вам нужно выполнить

object.first по предложению Jakub