2015-04-02 10 views
2

我的類如下所示,其中Customer使用單表繼承方法從User繼承。用戶具有屬性名稱和電子郵件,而訂單有目的地。基於代碼運行下面的代碼片段RoR:對has_many關係執行delete_all時的NoMethodError

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:對於無未定義的方法「名」: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>' 
+0

你能確切知道'name'是哪個模型的屬性嗎?看起來錯誤不是來自於delete_all方法 – Chambeur 2015-04-02 09:29:22

+1

您能否給出一個異常的堆棧跟蹤以及User,Customer和Order的完整源代碼。似乎有一些積極的記錄回調或驗證問題。 'new'和'create'之間的區別在於'create'立即運行所有回調,驗證並將對象保存在數據庫中,而'new'只在內存中創建對象。 – 2015-04-02 09:42:52

+0

@Chambeur我上面已經說明了,但也許我還不夠清楚。 用戶欄位=>姓名,電郵 訂單欄位=>目的地 – keylime 2015-04-02 10:29:29

回答

3

我想你是對的關於ruby版本的問題。 我發現這個question

這個傢伙有類似的問題,他通過將他的ruby版本從ruby-2.2.0切換到ruby-2.1.1來修復它。

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

+0

果然,這是Ruby版本。我的朋友的電腦運行2.1.5,所以我試圖降級到現在它找到了。謝謝。 – keylime 2015-04-02 13:42:35

+0

另一個選項當然是在Gemfile中啓動你的rails版本。我嘗試將我的引用切換到gem'rails','4.2.3'並運行軟件包更新並修復了問題 – Kalman 2016-03-31 16:16:10

+0

對於使用4.1的用戶,我升級到4.1.16並修復了問題 – 2016-11-21 01:03:45

1

嘗試更新您

has_many :orders, :dependent => :destroy 

has_many :orders, :dependent => :delete_all 

根據您想達到什麼樣的客戶類的關聯。

:destroy導致也被銷燬所有相關的對象。

:delete_all導致所有關聯對象直接從數據庫中刪除而不執行回調。

+0

給它一個鏡頭。不幸的是,不工作。 – keylime 2015-04-02 10:28:37

0

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']) 

destroy_all

例如

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

看起來您沒有反向關聯,並且Rails在更新緩存的計數器時無法解析訂單的客戶。試試這個:

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

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