web-dev-qa-db-fra.com

méthode de construction sur Ruby sur rails

Nouveau sur Rails et je suis le projet Depot trouvé dans le développement web Agile avec Rails 3.1. Tout allait bien jusqu'à ce que je me perde lorsque le livre est utilisé) la méthode "build".

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

Mes recherches sur Google m'ont amené à comprendre que la méthode .build n'est qu'un moyen plus propre de créer une ligne dans le tableau (avec association entre les tableaux). Mais sur le code ci-dessus, je m'attendais à ce que le code ressemble à quelque chose comme ceci:

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

Je ne comprends pas pourquoi l'auteur a dû stocker toute la ligne de produits (product = Product.find (params [: product_id])) au lieu de simplement obtenir le product_id ...

Y a-t-il plus que ce que je peux comprendre?

32
Finks

Vous avez mal compris build. C'est juste un alias de new, rien de spécial. https://github.com/Rails/rails/blob/959fb8ea651fa6638aaa7caced20d921ca2ea5c1/activerecord/lib/active_record/relation.rb#L84

build ne "créera" pas un enregistrement dans la base de données, il suffit de créer un nouvel objet en mémoire pour que la vue puisse prendre cet objet et afficher quelque chose, surtout pour un formulaire.

Pour votre deuxième question, oui, votre façon de composer par id fonctionnera également. Mais une meilleure approche consiste à ne pas faire confiance à param. Au lieu de cela, vérifiez-le en trouvant d'abord dans db.

59
Billy Chan

Je vais continuer et dire que vous avez tout à fait raison. L'une ou l'autre méthode fonctionne et fera la même chose, mais votre version utilisant simplement :product_id est plus efficace et nécessite une requête de base de données en moins. Cela dit, cela peut être utile si vous avez besoin de cette variable product plus tard dans le code ou si cet élément de campagne spécifique appelle product.{something} plus tard pour ne pas avoir à le récupérer par id à ce stade.

Cependant, je préférerais personnellement définir simplement le :product_id, Je ne vois aucune raison de trouver l'objet en premier.

1
nzifnab