购物车功能,Rails 3上的current_cart方法定义

时间:2013-06-04 11:59:36

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

我是Stackoverflow的新手,对于Web开发来说还是一个新手。 我已经学习了几个月的Rails,并开始构建一个简单的应用程序来自学。

我会尽量简明扼要,应用程序如下:用户注册或登录,以便他可以对自己的产品和客户执行CRUD操作。他还可以通过电话号码搜索客户,检索找到的客户或表单以创建新客户。很简单。现在,每个客户可以放置许多订单(或购物车,无论你想要什么叫它),这些订单存储许多产品,由给定客户在给定时间购买。 你可以在这里看到一个工作示例,http://order-checker.herokuapp.com带有模拟购物车功能,看看它们应该如何组合在一起。 用户:访客,密码:abcd1234

现在,我已经在购物车功能,订单项模型,控制器等方面编写了第二个示例,并且没有用户身份验证以简化操作。 https://github.com/gatosaurio/mockup 。以下是我的第二个例子的模型:

class Customer < ActiveRecord::Base
  attr_accessible :name, :street
  has_many :carts
end

class Product < ActiveRecord::Base
  attr_accessible :name, :price
end

class Cart < ActiveRecord::Base
  belongs_to :customer
  has_many :line_items
  attr_accessible :purchased_at

  def total_price
    line_items.to_a.sum(&:full_price)
  end
end

class LineItem < ActiveRecord::Base
  attr_accessible :cart_id, :product_id, :quantity, :unit_price
  belongs_to :cart
  belongs_to :product

  def full_price
    unit_price * quantity
  end
end

所以,在客户索引操作中,我为每一个都有一个new_cart_path链接。在购物车#new中,我想要一个所有产品的列表,其中包含“添加到订单”的帖子链接。

  <% @products.each do |product| %>
  <tr>
    <td><%= link_to product.name, product_path(product) %></td>
    <td><%= form_tag(line_items_path, :method => "post") do %>
        <%= hidden_field_tag(:product_id, product.id) %>
        <%= submit_tag("Add to Cart") %></td>
   <% end %>


  </tr>
<% end %>

此新购物车操作的侧边栏还应显示与此购物车相关的所有订单项,可能是这样的。

<% @cart.line_items.each do |line_item| %>
  <tr>
    <td><%= line_item.product.name %></td>
    <td class="qty"><%= line_item.quantity %></td>
    <td class="price"><%= number_to_currency(line_item.unit_price) %></td>
    <td class="price"><%= number_to_currency(line_item.full_price) %></td>
    <td><%= link_to "Delete", line_item, method: :delete, :limit => 1,  data: { confirm: 'Are you sure?'}%></td>
  </tr>
<% end %>
<tr>
  <td class="total price" colspan="4">
  <Total: <%= number_to_currency @cart.total_price %></td>
</tr>

现在,这里是line_items #create

def create
  @product = Product.find(params[:product_id])
  if LineItem.exists?(:cart_id => current_cart.id, :product_id => @product.id)
    item = LineItem.find(:first, :conditions => [ "cart_id = #{current_cart.id} AND product_id = #{@product.id}" ])
        LineItem.update(item.id, :quantity => item.quantity + 1)
  else  
        @line_item = LineItem.create!(:cart => current_cart, :product => @product, :quantity => 1, :unit_price => @product.price)
        flash[:notice] = "Added #{@product.name} to cart."
  end
redirect_to new_cart_path
end

所以你看,我的具体问题如何在application_controller.rb中定义current_cart方法?我问这个是因为我从谷歌搜索中找到的购物车功能的所有资源(带有Rails的敏捷Web开发,第4版)几乎专门用于创建会话对象购物车实例,但我发现这种方法不适合我的情况,因为我需要每个购物车只与一个特定客户相关联,而不是在应用程序用户级别上保持的会话。

我真的希望这是一个有效的问题,如果这个问题太长而且我当前的代表级别不允许我发布两个以上的链接,那么你可以在我的Github帐户上找到所有代码。

非常感谢:)

1 个答案:

答案 0 :(得分:1)

  # Shopping cart, id is in session (if any)
  def current_cart
    Cart.find(session[:cart_id])
  rescue ActiveRecord::RecordNotFound
    cart = Cart.create
    session[:cart_id] = cart.id
    cart
  end

购物车ID保存在会话中。如果未引用或找不到购物车,则会创建一个新购物车并将ID存储在会话中。无论哪种方式,都会返回购物车对象。

你最终会有很多空车或陈旧车。记得要设置清理工作。

附录

您的质量分配错误是此行的结果:

        @line_item = LineItem.create!(:cart => current_cart, :product => @product, :quantity => 1, :unit_price => @product.price)

在此处,您可以按质量分配创建新的LineItem。在您的模型中,您允许

的质量分配
  attr_accessible :cart_id, :product_id, :quantity, :unit_price

这里是棘手的部分:虽然Rails在内部分配id,但它确实需要你的配置。要大量分配到cart,您需要attr_accessible :cart。所以你可以

        @line_item = LineItem.create!(:cart_id => current_cart.id, :product_id => @product.id, :quantity => 1, :unit_price => @product.price)

  attr_accessible :cart, :cart_id, :product, :product_id, :quantity, :unit_price

两者都有效。