0

我真的很难追踪这个问题,现在我知道出了什么问题,但不知道为什么,以及它是否是一个错误。

macbuech:iq josh$ ruby -v
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.4.0]
macbuech:iq josh$ rails -v
Rails 3.2.1

我有一个Contact模型has_many :addresses。到目前为止一切正常,直到我决定验证 的存在Address.contact_id,这似乎破坏了my_contact.addresses << my_address功能!首先是它过去是如何工作的:

class Address < ActiveRecord::Base
  belongs_to :contact
  validates :contact, :presence => true
  # ...
end

class Contact < ActiveRecord::Base
  has_many :addresses
  # ...
end

这是 Rails 控制台中的测试输出:

1.9.3p0 :001 > c = FactoryGirl.create :contact
 => #<Contact id: 71, corporate: false, companyname: nil, firstname: nil, middlename: nil, lastname: "Doe", initials: nil, nickname: nil, gender: "male", title: nil, profession: nil, department: nil, birthday: nil, spouse: nil, kids: nil, superior: nil, assistant: nil, contacttype_id: 71, language_id: nil> 
1.9.3p0 :002 > a = FactoryGirl.create :address
 => #<Address id: 63, active: true, standard: false, street: "Mustergasse 123", extraline1: nil, extraline2: nil, city: "Musterhausen", zip: 8088, province: nil, pobox: nil, latitude: nil, longitude: nil, validfrom: nil, validto: nil, label: nil, description: nil, contact_id: 72, addresstype_id: 63, country_id: 63> 
1.9.3p0 :003 > c.addresses
 => [] 
1.9.3p0 :004 > c.addresses << a
 => [#<Address id: 63, active: true, standard: false, street: "Mustergasse 123", extraline1: nil, extraline2: nil, city: "Musterhausen", zip: 8088, province: nil, pobox: nil, latitude: nil, longitude: nil, validfrom: nil, validto: nil, label: nil, description: nil, contact_id: 71, addresstype_id: 63, country_id: 63>] 
1.9.3p0 :005 > c.addresses
 => [#<Address id: 63, active: true, standard: false, street: "Mustergasse 123", extraline1: nil, extraline2: nil, city: "Musterhausen", zip: 8088, province: nil, pobox: nil, latitude: nil, longitude: nil, validfrom: nil, validto: nil, label: nil, description: nil, contact_id: 71, addresstype_id: 63, country_id: 63>] 
1.9.3p0 :006 > c.save!
 => true 
1.9.3p0 :007 > c.reload
1.9.3p0 :008 > c.addresses
 => [#<Address id: 63, active: true, standard: false, street: "Mustergasse 123", extraline1: nil, extraline2: nil, city: "Musterhausen", zip: "8088", province: nil, pobox: nil, latitude: nil, longitude: nil, validfrom: nil, validto: nil, label: nil, description: nil, contact_id: 71, addresstype_id: 63, country_id: 63>]     

一切都按预期工作,地址#63 现在属于联系人#71。

然后我在这里读到验证belongs_to关系名称的存在没有多大意义,但我应该验证它的外键,所以我做了:

class Address < ActiveRecord::Base
  belongs_to :contact
  validates :contact_id, :presence => true
  # ...
end

所以这里是 Rails 控制台的日志,与上面的命令完全相同:

1.9.3p0 :009 > c = FactoryGirl.create :contact
 => #<Contact id: 84, corporate: false, companyname: nil, firstname: nil, middlename: nil, lastname: "Doe", initials: nil, nickname: nil, gender: "male", title: nil, profession: nil, department: nil, birthday: nil, spouse: nil, kids: nil, superior: nil, assistant: nil, contacttype_id: 84, language_id: nil> 
1.9.3p0 :010 > a = FactoryGirl.create :address
 => #<Address id: 74, active: true, standard: false, street: "Mustergasse 123", extraline1: nil, extraline2: nil, city: "Musterhausen", zip: 8088, province: nil, pobox: nil, latitude: nil, longitude: nil, validfrom: nil, validto: nil, label: nil, description: nil, contact_id: 85, addresstype_id: 74, country_id: 74> 
1.9.3p0 :011 > c.addresses
 => [] 
1.9.3p0 :012 > c.addresses << a
 => [#<Address id: 74, active: true, standard: false, street: "Mustergasse 123", extraline1: nil, extraline2: nil, city: "Musterhausen", zip: 8088, province: nil, pobox: nil, latitude: nil, longitude: nil, validfrom: nil, validto: nil, label: nil, description: nil, contact_id: 85, addresstype_id: 74, country_id: 74>] 
1.9.3p0 :013 > c.addresses
 => [#<Address id: 74, active: true, standard: false, street: "Mustergasse 123", extraline1: nil, extraline2: nil, city: "Musterhausen", zip: 8088, province: nil, pobox: nil, latitude: nil, longitude: nil, validfrom: nil, validto: nil, label: nil, description: nil, contact_id: 85, addresstype_id: 74, country_id: 74>] 
 => true 
1.9.3p0 :015 > c.reload
 => #<Contact id: 84, corporate: false, companyname: nil, firstname: nil, middlename: nil, lastname: "Doe", initials: nil, nickname: nil, gender: "male", title: nil, profession: nil, department: nil, birthday: nil, spouse: nil, kids: nil, superior: nil, assistant: nil, contacttype_id: 84, language_id: nil> 
1.9.3p0 :016 > c.addresses
 => [] 

如您所见,地址未正确分配给联系人!它:contact_id保持在 85 虽然它应该改变之后c.addresses << a!更可怕的是,当我删除整个验证时,它不起作用!

1.9.3p0 :009 > c = FactoryGirl.create :contact
 => #<Contact id: 97, corporate: false, companyname: nil, firstname: nil, middlename: nil, lastname: "Doe", initials: nil, nickname: nil, gender: "male", title: nil, profession: nil, department: nil, birthday: nil, spouse: nil, kids: nil, superior: nil, assistant: nil, contacttype_id: 97, language_id: nil> 
1.9.3p0 :010 > a = FactoryGirl.create :address
 => #<Address id: 85, active: true, standard: false, street: "Mustergasse 123", extraline1: nil, extraline2: nil, city: "Musterhausen", zip: 8088, province: nil, pobox: nil, latitude: nil, longitude: nil, validfrom: nil, validto: nil, label: nil, description: nil, contact_id: 98, addresstype_id: 85, country_id: 85> 
1.9.3p0 :011 > c.addresses
 => [] 
1.9.3p0 :012 > c.addresses << a
 => [#<Address id: 85, active: true, standard: false, street: "Mustergasse 123", extraline1: nil, extraline2: nil, city: "Musterhausen", zip: 8088, province: nil, pobox: nil, latitude: nil, longitude: nil, validfrom: nil, validto: nil, label: nil, description: nil, contact_id: 98, addresstype_id: 85, country_id: 85>] 
1.9.3p0 :013 > c.addresses
 => [#<Address id: 85, active: true, standard: false, street: "Mustergasse 123", extraline1: nil, extraline2: nil, city: "Musterhausen", zip: 8088, province: nil, pobox: nil, latitude: nil, longitude: nil, validfrom: nil, validto: nil, label: nil, description: nil, contact_id: 98, addresstype_id: 85, country_id: 85>] 
1.9.3p0 :014 > c.save!
 => true 
1.9.3p0 :015 > c.reload
 => #<Contact id: 97, corporate: false, companyname: nil, firstname: nil, middlename: nil, lastname: "Doe", initials: nil, nickname: nil, gender: "male", title: nil, profession: nil, department: nil, birthday: nil, spouse: nil, kids: nil, superior: nil, assistant: nil, contacttype_id: 97, language_id: nil> 
1.9.3p0 :016 > c.addresses
 => [] 

同样,:contact_id没有改变的相同场景......

非常感谢任何帮助,我已经浪费了大约 6 个小时来调查这个问题......

更新

我问的原因是我在 RSpec 文件中有以下内容:

let (:contact) do
  contact = create(:contact)
  contact.addresses << create(:address)
  contact
end

如前所述,这适用于validates :project, :presence => true,但它并非没有任何验证或validates :project_id, :presence => true.

我可以这样写,所以它可以与validates :project_id, :presence => true.

let (:contact) do
  contact = create(:contact)
  contact.addresses << create(:address, :contact => contact)
  contact
end
4

1 回答 1

0

在这种情况下,我总是会通过关联创建地址,即

c.addresses.create

那么当你这样做时会发生什么,在你的contact_id上进行验证?

于 2012-07-09T10:24:13.647 回答