【问题标题】:Shopping Cart functionality, current_cart method definition on Rails 3购物车功能,Rails 3 上的 current_cart 方法定义
【发布时间】:2013-06-04 11:59:35
【问题描述】:

我是 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 版)中找到的有关购物车功能的所有资源几乎都专门用于为cart 实例,但我发现这种方法不适合我的情况,因为我需要每个购物车仅与一个特定客户相关联,而不是在应用用户级别上举行会话。

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

非常感谢:)

【问题讨论】:

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


    【解决方案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
    

    两者都可以。

    【讨论】:

    • 感谢您的回答 :) 我几天前就这样做了,我想我应该在创建新的购物车对象后构建一个过滤器来清空购物车会话。问题是我收到以下错误:无法批量分配受保护的属性:购物车、产品我的模型显示在我原来的问题中。我在这里做错了什么?
    • 添加了批量分配解决方案来回答
    • 非常感谢!现在可以了! :) 我可以看到我想要的订单项。我重写了一点,如下所示: def current_cart session[:cart_id] ||= Cart.create!.id @current_cart ||= Cart.find(session[:cart_id]) end 现在我正在努力关联每个购物车给一个特定的客户,我想我会尝试使用嵌套属性来做到这一点。现在我想我还应该在 CartsController 中构建一个 after_filter,以便在创建购物车实例后将每个购物车会话设置为 nil。我会让你知道它是怎么回事。 Danke schön, hab' doch viel gelernt :)
    猜你喜欢
    • 2021-03-12
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多