2012-07-09 99 views
0

我真的很难跟踪这个问题,现在我知道发生了什么问题,但不知道为什么,以及它是否是一个错误。当联系人在地址中检查时,“联系has_many:地址”不起作用

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 

我有一个模型Contacthas_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。

然后我读here,它并没有多大意义,以验证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 

回答

0

在这样的情况下我总是会创建由协会地址,即

c.addresses.create 

,当你做到这一点,对你的CONTACT_ID验证会发生什么?

+0

这可以按预期工作,但我真的很想知道为什么我的代码的行为就像它一样,因为我怀疑这可能是一个错误或什么,或者,如果不是,它的解释是什么。 – 2012-07-09 10:50:20

相关问题