New to rails and I'm following the Depot project found in the Agile web development with rails 3.1. Everything was fine until I got lost when the book used the "build" method.
@cart = current_cart
product = Product.find(params[:product_id])
@line_item = @cart.line_items.build(product: product)
My google searches led me to understand that the .build method is just a cleaner way to create a row in the table (with association between tables). But on the code above, I was expecting the code would look like something like this:
@line_item = @cart.line_items.build(product_id => params[:product_id])
I don't understand why the author had to store the whole row of products( product = Product.find(params[:product_id])) instead of just getting the product_id...
Is there more to it than what I can understand?
My google searches led me to understand that the .build method is just a cleaner way to create a row in the table (with association between tables). But on the code above, I was expecting the code would look like something like this: @line_item = @cart.line_items.build(product_id => params[:product_id])
build ... produces an object with all nil values EXCEPT for list_id. Item. new creates a new item object, with all nil values.
. save is an “Instance Method”, it returns either true or false depending on whether the object was saved successfully to the database or not. If the model is new, a record gets created in the database, otherwise the existing record gets updated.
What is ActiveRecord? ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.
You misunderstood build
. It's just an alias of new
, nothing special. https://github.com/rails/rails/blob/959fb8ea651fa6638aaa7caced20d921ca2ea5c1/activerecord/lib/active_record/relation.rb#L84
build
won't "create" a record in database, just create a new object in memory so that the view can take this object and display something, especially for a form.
For your second question, yes, your way of composing by id will work as well. But a better approach is not to trust param. Instead, verify it by finding in db at first.
I'm going to go ahead and say you are entirely correct. Either method works and will do the same thing, but your version using just :product_id
is more efficient and requires one less database query. That said, it might make sense if you need that product
variable later in the code or that specific line item calls product.{something}
later so it doesn't have to fetch it by id at that point.
However, I personally would prefer to just set the :product_id
, I see no reason to find the object first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With