【问题标题】:Using after_create to update a cart's order_id使用 after_create 更新购物车的 order_id
【发布时间】:2014-05-22 21:42:34
【问题描述】:

首先,我有一个存储在会话中的购物车。购物车包含行项目(产品)。结帐按钮指向一个 Order.new 表单,其中 cart_id 传递给新订单(cart has_one order, order belongs_to cart)。

希望到目前为止一切顺利。

购物车参数包含一个 order_id,最初为 nil,直到用户点击结帐按钮。创建订单时,购物车中的 order_id 仍为 nil。如何在订单模型上使用 after_create 来更新购物车,使其现在具有有效的 order_id?

我的应用程序控制器中有一个 current_cart 方法,因此我可以在所有控制器中访问 c​​urrent_cart,但我无法在模型中访问它 -> 因为它存储在会话中,我听说我没有'无论如何都不想访问模型中的会话。

有人建议这样做吗?

我会显示一些代码以防我的描述不清楚。

orders_controller.rb

def create
  @cart = current_cart
  @order = @cart.build_order(order_params)
  if @order.save
    redirect_to @order, notice: "The order has been successfully created.  Below are your shipping options."
  else
    render action: "new"
  end
end

轨道控制台

>> @order.cart.order_id
=> nil

这真的很重要吗?也许我是偏执狂,但我认为从购物车中访问 order_id 以及从订单中访问 c​​art_id 是一个好习惯。

谢谢大家, 帕特

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 after-create


    【解决方案1】:

    您不需要在两个方向上存储 order_id,事实上,您可能会产生比您希望通过此设计解决的问题更多的问题。例如,当订单的购物车发生变化或相反时,您必须在两个方向上保持值最新。

    Rails 本身就足够聪明,即使在 Cart 模型上没有 order_id 时,它也可以确定哪条记录与哪条记录相关联:

    cart = Cart.last
    cart.order
    #=> #<Order ...>
    
    order = Order.last
    order.cart
    #=> #<Cart ...>
    

    我还想指出,您甚至可能不需要将Cart 持久化到数据库中,因为它仅在单个浏览器会话的上下文中才有意义。您可以改为将其设计为一个普通的旧 Ruby 对象(只是一个类,不继承自 ActiveRecord::Base)并进一步简化您的设计。

    【讨论】:

    • 您是否有任何关于不在会话中存储购物车的好处的阅读材料?我遵循了一个建议我这样做的教程。
    • 这不会有什么坏处,但是您认为将它存储在数据库中的好处是什么?当然,您可以将最终订单存储在数据库中,这绝对是有道理的。但是购物车?它的唯一目的是成为“草稿订单”,其最终目标是在下达实际订单后变得过时。再加上购物车本质上与会话的存在相关,我认为将其持久化到数据库中并不是真正必要的。毕竟,这只是我个人的看法。好处是:更少的查询,更少的无用数据(一旦下订单,它就会复制购物车)
    • 评论太长了,抱歉。另一个好处:代码更简单,因为不需要处理持久性。我可能会想到更多的好处 :-) 但是,如果你正在做一个教程,你最好坚持他们所说的;很有可能本教程将继续基于此模型。
    • 是的,这一切听起来都很棒。我无法想象我们的小型电子商务网站会有太多流量。我确信更大的操作会很大程度上受益于更少的查询。如果有一个教程,你会为你的方法推荐一个教程吗?我选择了这个,因为它很容易找到。
    猜你喜欢
    • 1970-01-01
    • 2021-03-17
    • 2014-08-29
    • 1970-01-01
    • 2017-04-05
    • 2016-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多