Подтвердить что ты не робот

Метод сборки на рубине на рельсах

Новое для рельсов, и я следую проекту Depot, найденному в веб-разработке Agile с рельсами 3.1. Все было в порядке, пока я не потерялся, когда книга использовала метод "build".

@cart = current_cart
product = Product.find(params[:product_id])
@line_item = @cart.line_items.build(product: product)

Мои поисковые запросы помогли мне понять, что метод .build - это просто более чистый способ создания строки в таблице (с ассоциацией между таблицами). Но в приведенном выше коде я ожидал, что код будет выглядеть примерно так:

@line_item = @cart.line_items.build(product_id => params[:product_id])

Я не понимаю, почему автору пришлось хранить всю строку продуктов (product = Product.find(params [: product_id])) вместо того, чтобы просто получить product_id...

Есть ли еще больше, чем я могу понять?

4b9b3361

Ответ 1

Вы неправильно поняли build. Это просто псевдоним new, ничего особенного. https://github.com/rails/rails/blob/959fb8ea651fa6638aaa7caced20d921ca2ea5c1/activerecord/lib/active_record/relation.rb#L84

build не будет "создавать" запись в базе данных, просто создайте новый объект в памяти, чтобы представление могло взять этот объект и отобразить что-то, особенно для формы.

Для вашего второго вопроса, да, ваш способ составления по id будет работать. Но лучший подход - не доверять параметру. Вместо этого проверьте его, сначала найдя в db.

Ответ 2

Я собираюсь пойти и сказать, что вы совершенно правы. Любой из этих методов работает и будет делать то же самое, но ваша версия с использованием только :product_id более эффективна и требует меньше запросов к базе данных. Тем не менее, это может иметь смысл, если вам понадобится эта переменная product позже в коде или эта конкретная позиция вызовет product.{something} позже, поэтому ей не нужно будет извлекать ее по id в этой точке.

Однако, я лично предпочел бы просто установить :product_id, я не вижу причин для поиска объекта в первую очередь.