当前位置: 动力学知识库 > 问答 > 编程问答 >

ruby on rails - Need to understand the syntax of line_items_path(product_id: product)

问题描述:

I am working through Iteration D3 of Agile Web Development in Rails 4 and I understood most of the code below except for the syntax line_items_path(product_id: product).

I understand that the code allows a product will be created through LineItemsController with reference to the product_id.

But I dont understand the syntax of the hash (product_id: product) as a parameter of line_items_path. why is there product after product_id:? Is it an overly simplified version of something?

<% @products.each do |product| %>

<div class="entry">

<%= image_tag(product.image_url) %>

<h3><%= product.title %></h3>

<%= sanitize(product.description) %>

<div class="price_line">

<span class="price"><%= number_to_currency(product.price, unit: '$') %></span>

<%= button_to 'Add to Cart', line_items_path(product_id: product) %>

</div>

</div>

<% end %>

网友答案:

This code:

line_items_path(product_id: product)

...is equivalent to this:

line_items_path({ :product_id => product })

In other words, you're passing one argument to the line_items_path method. That argument is a Hash. That Hash has a single key, which is the Symbol :product_id. The value being associated with that key is the value of the local variable product (product could also be a method name, but in this case it's the local variable passed to the block given to @products.each).

Edit

In reply to your comment: When you pass a Hash to a _url or _path helper, Rails assumes that its keys correspond to the bound parameters in the route, so if you have a route like /vendors/:id/products/:product_id, Rails will fill in :id and :product_id with the corresponding values from the Hash.

When that value isn't a number or string (or other primitive type), Rails will first try to call the to_param method on it. By default, an ActiveRecord object's to_param method will return the object's id, so if, for example, product is an instance of the Product model and its id is 123, then these four lines would yield the same result:

line_items_path(product_id: product)
line_items_path(product_id: product.to_param)
line_items_path(product_id: product.id)
line_items_path(product_id: 123)

For more information I recommend reading this answer: Where is the documentation on url helpers in rails? as well as the absolutely essential Rails Routing from the Outside In.

网友答案:

Yes - Rails will automagically call id on product in this circumstance.

网友答案:
line_items_path(product_id: product)

is a message send, sending the message line_items_path to the implicit receiver self, passing product_id: product as the argument.

If the last argument to a message send is a Hash literal, it is allowed to leave off the curly braces, and if the key of a key-value-pair in a Hash literal is a Symbol, it can optionally be written as sym: expr instead of :sym => expr.

Alternatively, if the line_items_path method has been defined to have keyword parameters, product_id: product could also be passing product as the value for the product_id keyword argument.

(The two syntaxes are deliberately identical to allow for a smooth transition towards keyword arguments.)

Last but not least, product is a local variable, more precisely a parameter binding of the block.

分享给朋友:
您可能感兴趣的文章:
随机阅读: