0

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

我会尽量简明扼要,应用程序是这样的:用户注册或登录,以便他可以对自己的产品和客户执行 CRUD 操作。他还可以通过电话号码搜索客户,检索找到的客户或表单以创建新客户。很简单。现在,每个客户都可以下许多订单(或购物车,无论您想怎么称呼它),其中存储了许多产品,这些产品是由给定客户在给定时间购买的。你可以在这里看到一个工作示例,http : //order-checker.herokuapp.com,它带有模拟的购物车功能,看看它应该如何组合在一起。用户:guest,密码: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 链接。在 carts#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 方法?我问这个是因为我可以从谷歌搜索(Agile Web Development with Rails,第 4 版)中找到的关于购物车功能的所有资源几乎专门处理为购物车实例创建会话对象,但我发现这个方法不适合我的情况,因为我需要每个购物车仅与一个特定客户相关联,而不是在应用程序用户级别上举行会话。

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

非常感谢 :)

4

1 回答 1

2
  # 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

两者都可以。

于 2013-06-04T13:04:49.917 回答