My app has both users and a shopping cart.
Theres currently no link between users and shopping carts.
At the moment regardless of if a user is logged in or not there is only one shopping cart available, the current_cart is created when a product is added and an order_transaction is created when the cart is paid for (success or fail). If successful, a new cart will be created the next time a product is added to the cart.
How can I link a cart with a user, so each user has a new cart created for them when adding a product?
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
routes
get "log_in" => "sessions#new", :as => "log_in"
get "log_out" => "sessions#destroy", :as => "log_out"
get "sign_up" => "users#new", :as => "sign_up"
get "cart" => "carts#show", :as => "current_cart"
resources :orders
resources :line_items
resources :carts
resources :products
resources :order_transactions
resou开发者_运维问答rces :sessions
resources :users
line_items_controller
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
Thanks for any help its much appreciated!
The easiest way to do this is to make the user have a cart
class User < ActiveRecord::Base
has_one :cart
def current_cart
if self.cart.empty?
self.cart.create!
end
self.cart
end
end
class Cart < ActiveRecord::Base
belongs_to :user
def add_line_item(item)
etc...
end
end
class ApplicationController < ActionController::Base
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
def current_cart
current_user.current_cart if current_user.present?
end
end
I would recommend this. That way, you only have ONE thing to keep track of in session. You should also try to move as much of the "business logic" DOWN to the model tier, to make it easier to test.
精彩评论