Agile Web Development with Rails, Edition 4

9.4 Playtime 9.2 Iteration D2: Connecting Products to Carts

9.3 Iteration D3: Adding a button

Expected at least 1 element matching "input[type=submit][value="Add to Cart"]", found 0.
<0> expected to be
>=
<1>.

Traceback:
  /home/rubys/git/awdwr/edition4/checkdepot.rb:149:in `block in <class:DepotTest>'

Now we connect the model objects we created to the controller and the view.

Add the button, connecting it to the Line Item Controller, passing the product id.

edit app/views/store/index.html.erb
<% if notice %>
<p id="notice"><%= notice %></p>
<% end %>
 
<h1>Your Pragmatic Catalog</h1>
 
<% cache ['store', Product.latest] do %>
  <% @products.each do |product| %>
    <% cache ['entry', product] do %>
      <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) %></span>
          <%= button_to 'Add to Cart', line_items_path(product_id: product) %>
        </div>
      </div>
    <% end %>
  <% end %>
<% end %>

Add a bit of style to make it show all on one line

edit app/assets/stylesheets/store.css.scss
    p, div.price_line {
      margin-left: 100px;
      margin-top: 0.5em; 
      margin-bottom: 0.8em; 
 
      form, div {
        display: inline;
      }
    }

See the button on the page

get /

Getting started

Here’s how to get rolling:

  1. Use bin/rails generate to create your models and controllers

    To see all available options, run it without parameters.

  2. Set up a root route to replace this page

    You're seeing this page because you're running in development mode and you haven't set a root route yet.

    Routes are set up in config/routes.rb.

  3. Configure your database

    If you're not using SQLite (the default), edit config/database.yml with your username and password.

Update the LineItem.new call to use set_cart and the product id. Additionally change the logic so that redirection upon success goes to the cart instead of the line item.

edit app/controllers/line_items_controller.rb
class LineItemsController < ApplicationController
  include CurrentCart
  before_action :set_cart, only: [:create]
  before_action :set_line_item, only: [:show, :edit, :update, :destroy]
 
  # GET /line_items
  #...
end
edit app/controllers/line_items_controller.rb
  def create
    product = Product.find(params[:product_id])
    @line_item = @cart.line_items.build(product: product)
 
    respond_to do |format|
      if @line_item.save
        format.html { redirect_to @line_item.cart,
          notice: 'Line item was successfully created.' }
        format.json { render :show,
          status: :created, location: @line_item }
      else
        format.html { render :new }
        format.json { render json: @line_item.errors,
          status: :unprocessable_entity }
      end
    end
  end

Try it once, and see that the output isn't very useful yet.

get /

Getting started

Here’s how to get rolling:

  1. Use bin/rails generate to create your models and controllers

    To see all available options, run it without parameters.

  2. Set up a root route to replace this page

    You're seeing this page because you're running in development mode and you haven't set a root route yet.

    Routes are set up in config/routes.rb.

  3. Configure your database

    If you're not using SQLite (the default), edit config/database.yml with your username and password.

Update the template that shows the Cart.

edit app/views/carts/show.html.erb
<% if notice %>
<p id="notice"><%= notice %></p>
<% end %>
 
<h2>Your Pragmatic Cart</h2>
<ul>    
  <% @cart.line_items.each do |item| %>
    <li><%= item.product.title %></li>
  <% end %>
</ul>

Try it once again, and see that the products in the cart.

get /

Getting started

Here’s how to get rolling:

  1. Use bin/rails generate to create your models and controllers

    To see all available options, run it without parameters.

  2. Set up a root route to replace this page

    You're seeing this page because you're running in development mode and you haven't set a root route yet.

    Routes are set up in config/routes.rb.

  3. Configure your database

    If you're not using SQLite (the default), edit config/database.yml with your username and password.

9.4 Playtime 9.2 Iteration D2: Connecting Products to Carts