Запрос как условный оператор в Ruby/Rails
-
21-12-2019 - |
Вопрос
Следил за приложением Depot от Agile Web Development with Rails.Был метод, который меня запутал.Я думал, что понял это, пока не попробовал это в irb.Итак, вот метод:
def add_product(product_id)
current_item = line_items.find_by_product_id(product_id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(product_id: product_id)
end
current_item
end
Насколько я понял, это просто метод, который сначала находит запись в LineItems с идентификатором продукта заданного ввода (скажем, 10).Затем он сохранит его в переменной current_item.Условие гласит: «Если идентификатор продукта был найден, добавьте 1 к количеству, иначе создайте новый экземпляр этой записи с идентификатором продукта, равным 10».
Вот снимок моей консоли Rails
Как видите, идентификатор продукта 10 в LineItem не найден.Но в моем состоянии это противоречит всему, во что я верил до сих пор.Может ли кто-нибудь пролить свет на это?
Решение
Выглядит как line
представляет собой пустую коллекцию (точнее, ActiveRecord::Relation), поэтому это что-то в Ruby, а не nil.Вот почему он возвращает true, когда вы звоните if line
и выполнение puts 'I'm true and happy'
.Причина, по которой это ActiveRecord::Relation, заключается в том, что вы используете где запрос.
В приложении Depot они делают запрос, вызывая line_items.find_by_product_id(product_id)
что отличается.Он находит первую запись, соответствующую условию.
Дополнительную информацию можно найти в руководствах по Rails здесь: http://guides.rubyonrails.org/active_record_querying.html (раздел 15)
PS Похоже, этот тип запроса устарел в Rails 4, поэтому не уверен, какую версию Agile Web Development with Rails вы ищете.