No route matches error when adding item to shopping cart from show page rails

时间:2016-07-11 19:42:30

标签: ruby-on-rails routes shopping-cart

I am trying to add an item from the product show page to a shopping cart. When the add to cart button is pressed a order_item is created in the database and sent to the cart. I have the add to shopping cart button working from the index page but when I try it from the show page I get the following error and nothing is added to the cart:

ActionController::RoutingError (No route matches [POST] "/products/5"):
  actionpack (4.2.5) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  web-console (2.3.0) lib/web_console/middleware.rb:20:in `block in call'
  web-console (2.3.0) lib/web_console/middleware.rb:18:in `catch'
  web-console (2.3.0) lib/web_console/middleware.rb:18:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.2.5) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.2.5) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:68:in `block in tagged'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.2.5) lib/rails/rack/logger.rb:20:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.6.4) lib/rack/methodoverride.rb:22:in `call'
  rack (1.6.4) lib/rack/runtime.rb:18:in `call'
  activesupport (4.2.5) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
  rack (1.6.4) lib/rack/lock.rb:17:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/static.rb:116:in `call'
  rack (1.6.4) lib/rack/sendfile.rb:113:in `call'
  railties (4.2.5) lib/rails/engine.rb:518:in `call'
  railties (4.2.5) lib/rails/application.rb:165:in `call'
  rack (1.6.4) lib/rack/lock.rb:17:in `call'
  rack (1.6.4) lib/rack/content_length.rb:15:in `call'
  rack (1.6.4) lib/rack/handler/webrick.rb:88:in `service'
  /usr/local/rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/webrick/httpserver.rb:140:in `service'
  /usr/local/rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/webrick/httpserver.rb:96:in `run'
  /usr/local/rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/webrick/server.rb:296:in `block in start_thread'

Product/show page:

<div class="col-xs-4">   
  <%= form_for '/order_item', remote: true do |f| %>
    <h4 class="text-right">Unit Price: <span style="color: green"><%= number_to_currency @product.price %></span></h4>
    <div class="input-group">
      <%= f.number_field :quantity, value: 1, class: "form-control", min: 1 %>
      <div class="input-group-btn">
        <%= f.hidden_field :product_id, value: @product.id %>
        <%= f.submit "Add to Cart", class: "btn btn-primary" %>
      </div>
    </div>
  <% end %>
</div>

order_items/create.js.erb

<% if @order.errors.any? || @order_item.errors.any? %>
  alert("not valid.")
<% else %>
  $(".cart-text").html("<%= escape_javascript(render 'layouts/cart_text') %>")
<% end %>

layouts/cart_text.html.erb

<%= link_to "#{current_order.order_items.size} Items in Cart (#{number_to_currency current_order.subtotal} )", cart_path, class: "btn btn-link" %>

carts/show.html.erb

<div class="shopping-cart">
  <%= render "shopping_cart" %>
</div>

carts/_shopping_cart.html.erb

<% if !@order_item.nil? && @order_item.errors.any? %>
  <div class="alert alert-danger">
    <ul>
      <% @order_item.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>

<% if @order_items.size == 0 %>
  <p class="text-center">
    There are no items in your shopping cart. Please <%= link_to "go back", root_path %> and add some items to your cart.
  </p>
<% else %>
  <% @order_items.each do |order_item| %>
    <%= render 'carts/cart_row', product: order_item.product, order_item: order_item, show_total: true %>
  <% end %>
<% end %>

carts_controller.rb

class CartsController < ApplicationController
  def show
    @order_items = current_order.order_items
  end
end

routes.rb

resources :products
resource :cart, only: [:show]
resources :order_items, only: [:create, :update, :destroy]

3 个答案:

答案 0 :(得分:0)

I'm not sure what you mean with your reference to the homepage, but this error is occurring because the request you're making (POST /products/5) doesn't have an appropriate route defined.

The “resourceful” routes provided by Rails map to the following HTTP verbs:

Rails Routing Verbs

I suspect that you're making a request to POST /products/:id when you intend to making a request to another endpoint.

答案 1 :(得分:0)

form_for should receive an ActiveRecord object, not a string as you are doing in form_for '/order_item'. This form is probably doing a POST to the same url, which should be products/5 that indeed doesn't exists.

Try to initialize a variable called @order_item in the ProductController#show method, and change your form declaration to something like form_for @order_item do |form|

答案 2 :(得分:0)

If the current_order is available in your view(which I think it is), from the layouts/cart_text, I think you should be doing:

<div class="col-xs-4">   
  <%= form_for current_order, remote: true do |f| %>
    <h4 class="text-right">Unit Price: <span style="color: green"><%= number_to_currency @product.price %></span></h4>
    <div class="input-group">
      <%= f.number_field :quantity, value: 1, class: "form-control", min: 1 %>
      <div class="input-group-btn">
        <%= f.hidden_field :product_id, value: @product.id %>
        <%= f.submit "Add to Cart", class: "btn btn-primary" %>
      </div>
    </div>
  <% end %>
</div>