Bohn
Bohn

Reputation: 26919

understanding how "button_to" works

In this code:

<

    % @products.each do |product| %>
      <div class="entry">
        <%= image_tag(product.image_url) %>
        <h3><%= product.title %></h3>
        <p><%= sanitize(product.description) %></p>
        <div class="price_line">
          <span class="price"><%= number_to_currency(product.price) %></span>
    <!-- START_HIGHLIGHT -->
          <%= button_to 'Add to Cart', line_items_path(product_id: product),
            remote: true %>
    <!-- END_HIGHLIGHT -->
        </div>
      </div>
    <% end %>

At the bottom where we have button_to method with the params passed to it:

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

Looking at the code, here is my understanding of what is going on, Did I understand it correctly or I have missed something?

In that code we are creating a button with text of "Add to Cart" and then we are passing the product_id of the prodcut varaible to it, which is coming from that for-each loop at the top and telling it go to link_items page with a POST method for a product with ID of product_id .

Another question: in the lines_items_path could we just pass product.product_id ? or that wouldn't work?

Upvotes: 0

Views: 228

Answers (2)

R Milushev
R Milushev

Reputation: 4315

I just understood your another question . The answer is : The code assigns the value of product.id to the symbol product_id . The symbol product_id is about to be used on the next step (probably for creating an association , in which the value of product_id is going to be a key) . Your question "why just product , but not product.id " will be reasonable one . The answer is in Rails framework's convention - if you'd like to use object's ID you just omit the .id part and Rails makes a guess correctly.

You cannot pass product.product_id , because the model Product does not have product_id method or property (which one you prefer) . It has .id .

Please , clarify the first part of your question .

EDIT (first part of the question- step by step)

@products.each do |product| - the loop iterates trough an array of objects (@products is array of objects , made up in the controller's action like this : @products= Product.all or similar ) . On every step the code inside do .. end operates on the local variable product . This is an object , which corresponds to one row of the database , thus it has "properties" (corresponding to columns) like product.id , product.name etc.

Then you create as many buttons as the count of the extracted db rows .

The information about which button is pressed , is carried by the new variable (in this case in form of a symbol - a special Ruby term , which deserves research :) ) So , you assign the value of product.id to it , like this : product_id: product.id . Summary : you made up the local variable product_id . The old style of this code : :product_id => product is more descriptive.

Upvotes: 1

gabrielhilal
gabrielhilal

Reputation: 10769

I think it is an example from the Agile Web Development with Rails book. I read it long time ago... if I remember it right, there are products, orders and line_items.

if you call rake routes you will se that line_items_path, as POST, is the route for thecreate action in the line_items_controller. More details: CRUD verbs and actions

So, you are passing the product_id to the create action, where you should have something like:

def create
  product = Product.find(params[:product_id])
...
end

Upvotes: 1

Related Questions