RoR:执行delete_all以获取has_many关系时的NoMethodError

时间:2015-04-02 09:20:42

标签: ruby-on-rails

我的类如下所示,Customer使用单表继承方法从User继承。用户具有属性名称和电子邮件,而订单具有目的地。

class User < ActiveRecord::Base
end

class Customer < User
  has_many :orders
end

class Order < ActiveRecord::Base
  belongs_to :customer
end

基于以下使用Rails控制台运行的代码片段

c = Customer.create
c.orders << Order.create
c.orders.delete_all

在最后一行执行delete_all函数会导致NoMethodError:未定义的方法&#39; name&#39;为零:NilClass。但是,以下工作。

c = Customer.new
c.orders << Order.create
c.orders.delete_all

在朋友的电脑上完全可以找到相同的作品。任何人都知道可能会发生什么?可能与我使用的某个版本中的错误有关吗?

堆栈跟踪

NoMethodError: undefined method `name' for nil:NilClass
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-    4.0.3/lib/active_record/associations/has_many_association.rb:81:in `cached_counter_attribute_name'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/associations/has_many_association.rb:77:in `has_cached_counter?'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/associations/has_many_association.rb:85:in `update_counter'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/associations/has_many_association.rb:125:in `delete_records'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:493:in `remove_records'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:486:in `block in delete_or_destroy'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:152:in `block in transaction'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `block in transaction'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:210:in `within_new_transaction'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:202:in `transaction'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/transactions.rb:209:in `transaction'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:151:in `transaction'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:486:in `delete_or_destroy'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:230:in `delete'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/associations/collection_association.rb:160:in `delete_all'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/activerecord-4.0.3/lib/active_record/associations/collection_proxy.rb:422:in `delete_all'
from (irb):6
from /home/leo/.rvm/gems/ruby-2.2.1/gems/railties-4.0.3/lib/rails/commands/console.rb:90:in `start'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/railties-4.0.3/lib/rails/commands/console.rb:9:in `start'
from /home/leo/.rvm/gems/ruby-2.2.1/gems/railties-4.0.3/lib/rails/commands.rb:62:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'

5 个答案:

答案 0 :(得分:3)

我猜你对红宝石版本的问题是正确的。 我找到了question

这家伙遇到了类似的问题,他通过将ruby版本从ruby-2.2.0切换到ruby-2.1.1来修复它。

如果它不是ruby版本,则可能是ActiveRecord版本。

答案 1 :(得分:3)

这是Ruby 2.2.2的Rails问题:https://github.com/rails/rails/issues/18991。它已在3.2.22中关闭并修复。

答案 2 :(得分:1)

尝试使用

更新客户类关联
has_many :orders, :dependent => :destroy

has_many :orders, :dependent => :delete_all

取决于您想要实现的目标。

:destroy导致所有相关对象也被销毁。

:delete_all会导致所有关联对象直接从数据库中删除而不执行回调。

答案 3 :(得分:0)

for delete_all

例如

 Post.delete_all("person_id = 5 AND (category = 'Something' OR category = 'Else')")
  Post.delete_all(["person_id = ? AND (category = ? OR category = ?)", 5, 'Something', 'Else'])

for destroy_all

例如

 Person.destroy_all("last_login < '2004-04-04'")
  Person.destroy_all(:status => "inactive")

答案 4 :(得分:0)

似乎您没有反向关联,并且Rails在更新缓存计数器时无法解析订单的客户。试试这个:

class Customer < User
  has_many :orders, inverse_of: :customer
end

class Order < ActiveRecord::Base
  belongs_to :customer, inverse_of: :orders
end