Search code examples
ruby-on-railsactivemerchantrailscasts

Adding items to a cart redirecting wrong


I've been following this Railscast on implementing Active Merchant in a new test app and it was going well, but now that I'm trying to add what I made to my main app its breaking.

When clicking 'add to cart' on my test app, it redirects to the current cart and lists the item as expected.

On my main app clicking the add to cart link redirects to:

http://mainapp.dev/line_items?product_id=1

The line_items controller looks like this:

class LineItemsController < ApplicationController
  def create
    @product = Product.find(params[:product_id])
    @line_item = LineItem.create!(:cart => current_cart, :product => @product, :quantity => 1, :unit_price => @product.price)
    flash[:notice] = "Added #{@product.name} to cart."
    redirect_to current_cart_url
  end
end

The add to cart link looks like this:

<%= link_to "Add to Cart", line_items_path(:product_id => product), :method => :post, :class => "product_actions" %>

edit - logs

Test version on adding an item (working):

Started POST "/line_items?product_id=5" for 127.0.0.1 at 2011-09-01 07:33:27 +0100
  Processing by LineItemsController#create as HTML
  Parameters: {"authenticity_token"=>"li7gkjksc9MENevuGz7emDwnbB6HrvPAE3CY=", "product_id"=>"5"}
  [1m[35mProduct Load (0.4ms)[0m  SELECT `products`.* FROM `products` WHERE `products`.`id` = 5 LIMIT 1
  [1m[36m (33.1ms)[0m  [1mBEGIN[0m
  [1m[35mSQL (179.4ms)[0m  INSERT INTO `carts` (`created_at`, `purchased_at`, `updated_at`) VALUES ('2011-09-01 06:33:28', NULL, '2011-09-01 06:33:28')
  [1m[36m (48.3ms)[0m  [1mCOMMIT[0m
  [1m[35m (0.2ms)[0m  BEGIN
  [1m[36mSQL (0.2ms)[0m  [1mINSERT INTO `line_items` (`cart_id`, `created_at`, `product_id`, `quantity`, `unit_price`, `updated_at`) VALUES (29, '2011-09-01 06:33:29', 5, 1, 250, '2011-09-01 06:33:29')[0m
  [1m[35m (0.5ms)[0m  COMMIT
Redirected to http://sell.dev/cart
Completed 302 Found in 1265ms


Started GET "/cart" for 127.0.0.1 at 2011-09-01 07:33:29 +0100
  Processing by CartsController#show as HTML
  [1m[36mCart Load (0.2ms)[0m  [1mSELECT `carts`.* FROM `carts` WHERE `carts`.`id` = 29 LIMIT 1[0m
  [1m[35mLineItem Load (0.3ms)[0m  SELECT `line_items`.* FROM `line_items` WHERE `line_items`.`cart_id` = 29
  [1m[36mProduct Load (0.5ms)[0m  [1mSELECT `products`.* FROM `products` WHERE `products`.`id` = 5 LIMIT 1[0m
Rendered carts/show.html.erb within layouts/application (202.1ms)
Rendered layouts/_header.html.erb (0.8ms)
Rendered layouts/_footer.html.erb (0.7ms)
Completed 200 OK in 368ms (Views: 284.2ms | ActiveRecord: 79.5ms)

The main app version:

Started GET "/line_items?product_id=1" for 127.0.0.1 at 2011-09-01 07:34:59 +0100
  Processing by LineItemsController#index as HTML
  Parameters: {"product_id"=>"1"}
Rendered line_items/index.html.erb within layouts/application (0.3ms)
Rendered layouts/_header.html.erb (1.3ms)
Rendered layouts/_footer.html.erb (178.4ms)
Completed 200 OK in 218ms (Views: 182.3ms | ActiveRecord: 35.5ms)

I can't figure out why it's wanting to redirect to the line items index and not create, the code is the same.

edit - routes

  get "cart" => "carts#show", :as => "current_cart"

  resources :orders
  resources :line_items
  resources :carts    
  resources :products
  resources :order_transactions

edit - taken from my application controller

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end

  def current_cart
    if session[:cart_id]
      @current_cart ||= Cart.find(session[:cart_id])
      session[:cart_id] = nil if @current_cart.purchased_at
    end
    if session[:cart_id].nil?
      @current_cart = Cart.create!
      session[:cart_id] = @current_cart.id
    end
    @current_cart
  end

Thanks for any help its much appreciated!


Solution

  • If you add an item to your cart by clicking on the link "Add to cart" then you will need to call the create action in the LineItemsController controller as you have it now.

    The last line of that method is

    redirect_to current_cart_url
    

    So you are indeed redirecting to the current_cart as you want but you are saying you are not redirecting to the current cart which is nonsense really.

    Perhaps you have not yet set up the current_cart_url path or views or something?

    I'm am not clear on what your actual problem is

    Started GET "/line_items?product_id=1" for 127.0.0.1 at 2011-09-01 07:34:59 +0100
      Processing by LineItemsController#index as HTML
      Parameters: {"product_id"=>"1"}
    Rendered line_items/index.html.erb within layouts/application (0.3ms)
    Rendered layouts/_header.html.erb (1.3ms)
    Rendered layouts/_footer.html.erb (178.4ms)
    Completed 200 OK in 218ms (Views: 182.3ms | ActiveRecord: 35.5ms)
    

    There MUST be something happening after this! ~What is it?

    edit - solution Sorry, I totally missed the obvious.

    <%= link_to "Add to Cart", line_items_path(:product_id => product), :method => :post, :class => "product_actions" %>
    

    is issuing a get request NOT a post request as indicated by your log file Started GET "/cart" for 127.0.0.1 at 2011-09-01 07:33:29 +0100

    You are adding an item to the cart which means you are changing state on the server which means you should be using a POST request NOT a get (link) request and therefore you should use a form (button_to will give you that form). Unless you want loads of bot's spiders;/crawlers etc... adding stuff to your cart you should use

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