ActiveRecord Rescue from View

时间:2014-06-13 16:56:51

标签: ruby-on-rails ruby activerecord rescue

我构建了一个小小的电子商务解决方案。在订单结束时,我希望购物车能够删除,因此用户在订购后无法访问同一购物车。在渲染order_confirmation页面后,我有一个删除购物车的after_action [:show]。如果刷新,订单确认页面将无法正常工作,因为订单项(用户购买的商品)已被购物车销毁。

这很好,我已经给他们发了一封电子邮件,如果他们刷新了确认页面,我就像一个activerecord :: recordnotfound rescue。

我的观点看起来像这样

         <% @order.items.each do |id| %>
         <% @line_item = LineItem.find(id) %>
         (line item data to show)

刷新时,line_items会删除,并且会收到activerecord错误。

Couldn't find LineItem with id=8

由于这是从视图中调用的,并且不是完全传统的 - 我如何进行救援以重定向并说出像#34;你的购物车重置&#34;或类似的规定?我尝试将它放在控制器中,但它没有被触及(或者没有触发......)

after_action :remove_cart, only: [:show]
 def index
  @orders = Order.all
 end

 def show
    @order = Order.find(params[:id])
    @cart = current_cart
    rescue ActiveRecord::RecordNotFound
          logger.error "User Refresh Page"
          redirect_to products_path
        raise
 end

如果超级建议不要在视图中有这样的循环,应该在控制器中创建一个数组,然后在视图上循环它们并在控制器中创建救援?

更新:

remove_cart方法非常直率,看起来像这样。

def remove_cart
  @cart = current_cart
  @cart.destroy
end

更新

我已经遵循达米恩的指示,但是在提交之后

给了我这个

   (6.2ms)  COMMIT
   undefined method `true=' for #<Cart:0x00000106b9fb98>
   Redirected to http://localhost:3000/orders/8
   Completed 302 Found in 1933ms (ActiveRecord: 19.4ms)

with order.rb

 after_commit :archive_cart, on: :create
 private

 def archive_cart
   cart.archive!
 end

和cart.rb为

def archive!
  update_attribute(active, false)
end

1 个答案:

答案 0 :(得分:1)

这是基于我们正在进行的对话,在这里:

http://chat.stackoverflow.com/rooms/55591/discussion-between-peege151-and-damien-roche


1。更新您的Order模型以包含:

class Order
  belongs_to :cart
  has_many :line_items, through: :cart
end

然后,在您看来:

<% @order.line_items.each do |line_item| %>

2。如meager所述,您应该归档订单详细信息。在购物车中添加状态,例如:

add_column :carts, :active, :boolean, default: true

然后,而不是控制器中的@cart = current_cart,而是直接通过cart参考@order.cart


3。将destroy / archive_cart逻辑移动到模型中

注意:这不是正常行为 - Order通常会有statuscart会在确认Order时归档,但提问者是使用初步模型(OrderPreview),其中每个新Order都已预先确认。

class Order
  after_commit :archive_cart, on: :create

  private

  def archive_cart
    cart.archive!
  end
end

class Cart
  def archive!
    update_attribute(:active, false)
  end
end