CartsController#destroy 中的 NoMethodError - 使用 Rails 4 进行敏捷 Web 开发 [英] NoMethodError in CartsController#destroy - Agile Web Development with Rails 4

查看:60
本文介绍了CartsController#destroy 中的 NoMethodError - 使用 Rails 4 进行敏捷 Web 开发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在按照《使用 Rails 4 进行敏捷 Web 开发》这本书学习 Rails,但遇到了这个错误:

I'm learning Rails following the book Agile Web Development with Rails 4 and I got stuck with this Error:

NoMethodError in CartsController#destroy
undefined method `name' for nil:NilClass

这是 Cart 控制器的 Destroy 操作.错误信息引用了行 @cart.destroy if @cart.id == session[:cart_id]:

This is the action Destroy of the Cart controller. The error info references to the line @cart.destroy if @cart.id == session[:cart_id]:

# DELETE /carts/1
# DELETE /carts/1.json
def destroy
  @cart.destroy if @cart.id == session[:cart_id]
  session[:cart_id] = nil
  respond_to do |format|
    format.html { redirect_to store_url,
     notice: 'Your cart is currently empty'}
    format.json { head :no_content }
  end
end

这个动作是从views/carts/shown.html.erb

<%= button_to 'Empty cart', @cart, method: :delete, data: {confirm: 'Are you sure?'} %>

一切正常,但在创建将 price 列添加到表 LineItems 的迁移并修改 add_product 中的方法后 add_productcode>Carts 用于处理这个新列,destroy 操作不再起作用.

Everything was working fine, but after creating a migration that added the column price to the table LineItems and modifying the method add_product from Carts for handling this new column, the destroy action is not working anymore.

这是models/cart.rb

class Cart < ActiveRecord::Base
  has_many :line_items, dependent: :destroy

  def add_product(product_id, product_price)
    current_item = line_items.find_by(product_id: product_id)
    if current_item
      current_item.quantity += 1
    else
      current_item = line_items.build(product_id: product_id, price: product_price)
    end
    current_item
  end

  def total_price
    line_items.to_a.sum { |item| item.total_price }
  end

end

这是models/line_item.rb:

class LineItem < ActiveRecord::Base
  belongs_to :product
  belongs_to :cart

  def total_price
    price * quantity
  end
end

这是来自 line_items_controller 的操作 create,用于将产品添加到购物车:

And this is the action create from line_items_controller that is used for adding products to the Cart:

before_action :set_cart, only: [:create]

...

# POST /line_items
# POST /line_items.json
def create
  session[:counter] = 0
  product = Product.find(params[:product_id])
  @line_item = @cart.add_product(product.id, product.price)

  respond_to do |format|
    if @line_item.save
      format.html { redirect_to @line_item.cart }
      format.json { render action: 'show', status: :created, location: @line_item }
    else
      format.html { render action: 'new' }
      format.json { render json: @line_item.errors, status: :unprocessable_entity }
    end
  end
end

在此操作之前,将调用 CurrentCart 模块中的 set_cart 方法:

Before this action, the method set_cart from the module CurrentCart is called:

def set_cart
  @cart = Cart.find(session[:cart_id])
  rescue ActiveRecord::RecordNotFound
  @cart = Cart.create
  session[:cart_id] = @cart.id
end

当我运行控制器测试时,没有失败.这是对 Cart 中 destroy 操作的测试:

When I run the controllers tests there are no failures. This is the test for the action destroy from Cart:

test "should destroy cart" do
  assert_difference('Cart.count', -1) do
    session[:cart_id] = @cart.id
    delete :destroy, id: @cart
  end

  assert_redirected_to store_path
end

我看不出这个错误的原因是什么,我需要你的帮助.

I can't see what is the cause of this error and I would like your help.

编辑

这是来自服务器的输出:

This is the output from the server:

Started DELETE "/carts/15" for 127.0.0.1 at 2015-02-16 12:23:43 -0500
Processing by CartsController#destroy as HTML
  Parameters: {"authenticity_token"=>"hLsBQ0fR5b9M2lfxMc5McU1+dqtnZ2OKABRZV79vdHo=", "id"=>"15"}
  Cart Load (0.2ms)  SELECT "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT 1  [["id", "15"]]
   (0.2ms)  begin transaction
  LineItem Load (0.9ms)  SELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = ?  [["cart_id", 15]]
  SQL (0.5ms)  DELETE FROM "line_items" WHERE "line_items"."id" = ?  [["id", 91]]
   (0.2ms)  rollback transaction
Completed 500 Internal Server Error in 73ms

NoMethodError (undefined method `name' for nil:NilClass):
  app/controllers/carts_controller.rb:58:in `destroy'

谢谢:)

推荐答案

从 rails 控制台尝试并得到这个:

Tried from rails console and got this:

2.2.0 :001 > carro = Cart.find(25)
  Cart Load (12.9ms)  SELECT "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT 1  [["id", 25]]
 => #<Cart id: 25, created_at: "2015-02-17 01:10:49", updated_at: "2015-02-17 01:10:49"> 
2.2.0 :002 > carro.destroy
   (0.2ms)  begin transaction
/home/xx/.rvm/gems/ruby-2.2.0/gems/activerecord-4.0.0/lib/active_record/associations/has_many_association.rb:75: warning: circular argument reference - reflection
/home/xx/.rvm/gems/ruby-2.2.0/gems/activerecord-4.0.0/lib/active_record/associations/has_many_association.rb:79: warning: circular argument reference - reflection
/home/xx/.rvm/gems/ruby-2.2.0/gems/activerecord-4.0.0/lib/active_record/associations/has_many_association.rb:83: warning: circular argument reference - reflection
/home/xx/.rvm/gems/ruby-2.2.0/gems/activerecord-4.0.0/lib/active_record/associations/has_many_association.rb:102: warning: circular argument reference - reflection
  LineItem Load (0.2ms)  SELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = ?  [["cart_id", 25]]
  SQL (0.3ms)  DELETE FROM "line_items" WHERE "line_items"."id" = ?  [["id", 116]]
  SQL (0.1ms)  DELETE FROM "line_items" WHERE "line_items"."id" = ?  [["id", 117]]
  SQL (0.1ms)  DELETE FROM "line_items" WHERE "line_items"."id" = ?  [["id", 118]]
   (0.2ms)  rollback transaction
NoMethodError: undefined method `name' for nil:NilClass
    from /home/xx/.rvm/gems/ruby-2.2.0/gems/activerecord-4.0.0/lib/active_record/associations/has_many_association.rb:80:in `cached_counter_attribute_name'

会发生什么 /home/xx/.rvm/gems/ruby-2.2.0/gems/activerecord-4.0.0/lib/active_record/associations/has_many_association.rb:75: 警告:循环论证参考 - 反射是由 activerecord 中的错误引起的,根据这个 GitHub 问题.

What happens is that /home/xx/.rvm/gems/ruby-2.2.0/gems/activerecord-4.0.0/lib/active_record/associations/has_many_association.rb:75: warning: circular argument reference - reflection is caused for a bug in activerecord according to this GitHub issue.

我所做的是更新 rails 版本.我使用的是 rails 4.0.0,更新到 rails 4.1.2 后问题解决了.

What I did was update the rails version. I was using rails 4.0.0, after updating to rails 4.1.2 the problem was solved.

这篇关于CartsController#destroy 中的 NoMethodError - 使用 Rails 4 进行敏捷 Web 开发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆