1

在我的edit行动中,我employees_controller有这行代码:

#Employee#edit
69: if @employee.user.person.addresses.length == 0
70:   @employee.user.person.addresses << Address.new
71: end

Address如果没有,它应该添加一个空白,这样它将显示在我的编辑 erb 文件中。这样,如果没有与该员工关联的地址,他们将在编辑此记录时强制添加一个。

有一个像这样的多态关联:Person <- User <- Employee并且与Person具有多对多关系Address。该声明如下所示:

#class Person
has_many :address_person_links, :dependent => :destroy
has_many :addresses,
  :through => :address_person_links,
  :uniq => true,
  :validate => false, # I thought this would fix it but doesn't
  :dependent => :destroy

代码在第 70 行失败employees_controller.rb

/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:1090:in `save_without_dirty!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/dirty.rb:87:in `save_without_transactions!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in `save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:182:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in `save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in `save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/has_many_through_association.rb:63:in `insert_record'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:119:in `<<'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:433:in `add_record_to_target_with_callbacks'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:118:in `<<'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:116:in `each'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:116:in `<<'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:141:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:182:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:140:in `transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/associations/association_collection.rb:115:in `<<'
/home/aaron/NetBeansProjects/onlinescheduler/app/controllers/employees_controller.rb:70:in `edit'

注意它的调用方式save?为什么要这样做?

4

2 回答 2

1

发生这种情况是因为每当您将 AR 对象添加到关联数组时,它都会保存该对象并尝试将其 id 添加到关联表中(如果它是 many_to_many)

您可以尝试以下方法

#Employee#edit
69: if @employee.user.person.addresses.length == 0
70:   @employee.user.person.addresses = [Address.new]
71: end

此外,如果您accepts_nested_attributes_for按照惯例执行此操作,则使用该build方法

#Employee#edit
69: if @employee.user.person.addresses.length == 0
70:   @employee.user.person.addresses.build
71: end

有关更多信息,请参阅http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes

于 2010-05-09T05:12:45.520 回答
1

首先,为了语义清晰,我建议您检查如下:

if @employee.user.person.addresses.empty?

接下来,如果您检查日志,您将看到地址(以及相应的 address_person_link)通过“<<”方法添加到数据库中,这反过来又调用验证,这就是您保存失败的原因(作为新创建的地址不验证)。

如果它是新创建的记录,您可以修改您的地址验证以避免运行它们(例如当您刚刚使用“<<”将其添加到一个人时。像这样:

validates_presence_of :name, :unless => Proc.new{|a|a.new_record?}

您必须将 :unless 块添加到地址验证中的每个块中。

于 2010-05-09T05:18:47.043 回答