简体   繁体   中英

How Does Rails Determine This id's Value?

Coming from Java, a highly explicit language, to RoR, which uses a very terse syntax, is easy for the most part, but I'm struggling to understand a few of the things that are going on behind the scenes.

In the code below, how does Rails assign product_id: a value? Couldn't product.id be used instead? What does the product_id: mean exactly in this context? Where does its value come from?

In the view:

<% @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 %>

Is it because of the attr_accessible statements I gave in my line_items model?:

class LineItem < ActiveRecord::Base
  attr_accessible :cart_id, :product_id
  belongs_to :product
  belongs_to :cart
end

It probably means that you have a route that expects a product_id , and the "Add to Cart" link is linking to that route's URL, and passing the id for product in that URL. I belive doing line_items_path(product_id: product) is the same as doing line_items_path(product_id: product.id) .

Actually, belongs_to :product is what gives your model (LineItem) this attribute. So now you can reference the parent product (that this LineItem belongs to), by doing for example LineItem.find(1).product_id , which would return the same as doing LineItem.find(1).product.id .

Rails uses this conventional attribute (product_id) as it directly maps to the table column. Check your schema.rb file, you will find it there, inside the line_items table.

It'll call the #to_param method, which by default returns the id.

As you come from Java, I'd say it's similar as when you do System.out.println(anObject) which calls implicitly the #toString() method

product_id is a parameter that line_items_path route is expecting. You can just pass an object instead of setting it manually:

line_items_path(product)

Result should be the same. If you rename it in your routes, it would break your views, so it's better not to manually set it.

line_items_path(product_id: product)

Is equivalent to

line_items_path(:product_id => product)

Which is the same as

line_items_path({:product_id => product})

In this specific case product_id behaves like a symbol literal ( normally you need the leading : or %s[]). This alternative, more json-like hash syntax was added in ruby 1.9.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM