While what you are asking is about 20 questions, I will answer this. The
functionality you are looking for with your shopping cart would really
require you to persist the card and items as a database table. Then write
logic to save it when things are added/removed and to recall it from the DB
when a use logs in. A session is not the right place for this type of
functionality. The problem with long running carts, is that if you change
the price on something you may have a persisted cart item that has a
differnet price, so you need to decide if you persist the price when the
user adds items to the cart, or you keep it linked to the product that may
change over time.
-Jake
On 10/18/07, elle <waznelle-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:>
>
> Hi,
>
> I guess as many people, I am very new to Rails. I used a book to
> create a shopping cart and then modified the code to try and fit it to
> my project''s requirements. I have been trying figure this out for
the
> last week and starting to get really discouraged about the prospects
> of solving this. I know what needs to be done but I''m at a loss
for
> how to achieve it. So, I wanted to ask, for help. Please please
> please.
>
> Background:
> I have the following classes: customer, product, cart, cart_items,
> order, order_items
> A customer needs to login to even see the "Add to cart" links --
so
> the same goes for viewing cart and checkout. (which is achieved).
> Things I have trouble with:
> 1) The sessions are stored in the db. Right now, customer session and
> cart session are separate. I need to assoociate them together. So,
> when a customer loggs out and a new customer logs in, they have
> different carts. If the session can remember the cart items, if the
> same customer logs in again, that would be great. The customer id will
> also need to be stored in the orders tables as well.
> 2) I suddently have trouble even trying to add an item to the cart.
> 3) I need to figure out a way to update the quantity of items
> (products) in the cart.
> 4) And lastly, my checkout page doesn''t come up suddenly as well
>
> Please can anyone have a look and help me solve this?
> Any help will be so much appreciated,
> Thanks,
> Elle
>
> -------------------------------------------
> MODELS
> customer.rb:
>
> class Customer < ActiveRecord::Base
> has_many :orders,
> :dependent => true,
> :order => "created_at ASC"
> has_many :carts
>
> validates_length_of :name, :within => 3..40
> validates_uniqueness_of :name
> validates_length_of :password, :within => 4..40, :if
> => :password_required?
>
> def open_orders
> orders.find(:all, :conditions => "status =
''open''")
> end
>
> def orders_history
> orders.find(:all, :conditions => "status =
''closed''")
> end
>
> def password=(value)
> write_attribute("password", Digest::SHA1.hexdigest(value))
> end
>
> def self.authenticate(name,password)
> find(:first, :conditions => ["name = ? and password =
?",name,
> Digest::SHA1.hexdigest(password)])
> end
>
> def self.orders
> current_customer = Customer.find(param[:id])
> orders = current_customer.orders
> end
>
> def self.carts
> current_customer = Customer.find(param[:id])
> orders = current_customer.carts
> end
>
> end
>
> ------------------------------
> cart.rb:
>
> class Cart < ActiveRecord::Base
> has_many :cart_items
> has_many :products, :through => :cart_items
> belongs_to :customer
>
> def total
> cart_items.inject(0) {|sum, n| n.price * n.amount + sum}
> end
>
> def add(product_id)
> items = cart_items.find_all_by_product_id(product_id)
> product = Product.find(product_id)
> if items.size < 1
> ci = cart_items.create(:product_id => product_id,
> :amount => 1,
> :price => product.price)
> else
> ci = items.first
> ci.update_attribute(:amount, ci.amount + 1)
> end
> ci
> end
>
> def remove(product_id)
> ci = cart_items.find_by_product_id(product_id)
>
> if ci.amount > 1
> ci.update_attribute(:amount, ci.amount - 1)
> else
> CartItem.destroy(ci.id)
> end
> return ci
> end
>
> def update(product_id)
> items = cart_items.find_all_by_product_id(product_id)
> product = Product.find(product_id)
> ci = cart_items
> ci.update_attribute(:amount, ci.amount + 1)
>
> end
>
> end
>
> -------------------------------
> CONTROLLER
> cart_controller.rb:
>
> class CartController < ApplicationController
> before_filter :initialize_cart
> before_filter :authorize, :except => ["login"]
>
> def authorize
> return true if @c
> flash[:notice] = "To place your order please login"
> redirect_to :controller => "catalog"
> end
>
> def login
> # examine the form data for "name" and "password"
> pw,name = params[:customer].values_at(*%w{password name})
> # Retrieve the customer record for the name and store it in a
> variable ''c''
> c = Customer.find_by_name(name)
> # if such record exists, and it''s password matches the
password
> from the form
> if c && Digest::SHA1.hexdigest(pw) == c.password
> # start a session with the customer id
> session[:customer] = c.id
> @cart = Cart.create
> session[:customer]
>
> if @cart.products.empty?
> redirect_to :controller => "catalog"
> else
>
> redirect_to :action => "view_cart"
> end
> else
> # otherwise report an error
> flash[:notice] = "Invalid Login"
> redirect_to :controller => "catalog"
> end
> end
>
> def logout
> session[:customer] = nil
> redirect_to :controller => "catalog"
> end
>
> def index
> end
>
> def add
> product = Product.find(params[:id])
> if request.post?
> @item = @cart.add(params[:id])
> flash[:notice] = "Added
<em>#{@item.product.title}</em> to
> cart."
> redirect_to :controller => "catalog"
> else
> render
> end
> end
>
> def update
> @product = Product.find(params[:id])
> if request.post?
> @item = @cart.update_attributes(params[:cart])
> flash[:notice] = "Updated
<em>#{@item.product.title}</em>''s
> quantity."
> redirect_to :action => "view_cart" and return if
@cart.save
> else
> render
> end
> end
>
> def remove
> @product = Product.find(params[:id])
> if request.post?
> @item = @cart.remove(params[:id])
> flash[:notice] = "Removed
<em>#{@item.product.title}</em>"
> redirect_to :action => "view_cart"
> else
> render
> end
> end
>
> def clear
> if request.post?
> @cart.cart_items.destroy_all
> flash[:notice] = "Cleared the cart"
> redirect_to :controller => "catalog"
> else
> render
> end
> end
>
> def view_cart
> @page_title = "Shopping Cart for #{@c.name}"
> @order = Order.new
> if @cart.empty?
> flash[:notice] = "Your shopping cart is empty! Please add
> something to it before proceeding to checkout."
> redirect_to :controller => ''catalog''
> end
> end
>
> def checkout
> @page_title = "Checkout"
> @order = Order.new(params[:order])
> @order.customer_ip = request.remote_ip
> @order.customer_id = @session[''customer'']
> populate_order
>
> if @order.save
> if @order.process
> flash[:notice] = ''Your order has been submitted, and will
be
> processed immediately.''
> session[:order_id] = @order.id
> # Empty the cart
> @cart.cart_items.destroy_all
> redirect_to :action => ''thank_you''
> else
> flash[:notice] = "Error while placing order.
> ''#{@order.error_message}''"
> render :action => ''view_cart''
> end
> else
> render :action => ''view_cart''
> end
> end
>
> def thank_you
> @page_title = ''Thank You!''
> end
>
>
> def populate_order
> for cart_item in @cart.cart_items
> order_item = OrderItem.new(
> :product_id => cart_item.product_id,
> :price => cart_item.price,
> :amount => cart_item.amount
> )
> @order.order_items << order_item
> end
> end
>
> end
>
> ------------------------------------------
> VIEWS
> partial for cart item: _item.rhtml:
>
> <tr>
> <td><%=h item.product.sku %></td>
> <td><%= link_to item.product.title, :action =>
"show",
> :controller => "catalog", :id => item.product.id
%></td>
> <td><%= pluralize(item.amount, "pc", "pcs")
%></td>
> <td>$<%= two_dec(item.price * item.amount) %></td>
>
> <td><%= form_tag :controller => "cart", :action =>
"update", :id =>
> item.product, :with => "new_qty" %>
> <%= text_field_tag "new_qty", "", "size"
=> 4 %>
> <input type="Submit", value="Update"/>
> <%= end_form_tag %>
> </td>
> <td><%= button_to "x", :controller =>
"cart", :action => "remove", :id
> => item.product %></td>
> </tr>
>
> -------------------------------------------------
> checkout.rhtml:
>
> <%= error_messages_for ''order'' %>
> <p><em>Your order’s total is: <%=h @cart.total
%></em></p>
> <form method="post" id="checkout"
action="<%= url_for :action
> => :checkout %>">
> <fieldset>
> <legend>Contact Information</legend>
> <p><label
for="order_email">Email</label></p>
> <p><%= text_field :order, :email %></p>
>
> <p><label for="order_phone_number">Phone
number</label></p>
> <p><%= text_field :order, :phone_number %></p>
> </fieldset>
>
> <fieldset>
> <legend>Shipping Address</legend>
> <p><label for="order_ship_to_first_name">First
name</label></p>
> <p><%= text_field :order, :ship_to_first_name %></p>
>
> <p><label for="order_ship_to_last_name">Last
name</label></p>
> <p><%= text_field :order, :ship_to_last_name %></p>
>
> <p><label
for="order_ship_to_address">Address</label></p>
> <p><%= text_field :order, :ship_to_address %></p>
>
> <p><label
for="order_ship_to_city">City</label></p>
> <p><%= text_field :order, :ship_to_city %></p>
>
> <p><label
for="order_ship_to_postal_code">Postal/Zip code</label></
> p>
> <p><%= text_field :order, :ship_to_postal_code %></p>
>
> <p><label
for="order_ship_to_country">Country</label></p>
> <p>
> <select name="order[ship_to_country]"
id="order_ship_to_country">
> <option value="US">United States</option>
> <option value="CA">Canada</option>
> </select>
> </p>
> </fieldset>
>
>
> <p> <%= submit_tag "Place Order" %> </p>
> </form>
>
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---