Rails 3.1:通过.build创建对象似乎与validates_presence_of冲突



我在结合外键字段的验证以及使用.build方法来创建对象时遇到了麻烦。参见下面的类。

class Parent < ActiveRecord::Base
  belongs_to :family
  has_one    :family_user
  validates_presence_of  :name
  validates_associated   :family 
  validates_presence_of  :family_id
end
class Family < ActiveRecord::Base
  belongs_to  :organization
  has_many    :parents
  ...
end

这通常工作得很好,但在应用程序中我想使用构建方法。例如,下面的代码在规范和rails控制台中都失败了,因为它正在查找Parent记录上的family_id。

  fam = Family.new(:organization_id => 1)
  fam.children.build(:name => "Billy Jones")
  fam.parents.build(:name => "Mister Jones")
  fam.save!  

如果没有validates_presence_of :family_id,该代码可以工作,并且确实正确记录了family_id。

问题:是否有一种方法来验证一个family_id确实被记录,同时也能够使用。build?

作为参考,控制台中的错误是:

ruby-1.9.2-p290 :082 > fam = Family.new(:organization_id => 1)
 => #<Family id: nil, organization_id: 1, created_at: nil, updated_at: nil, url_token: nil> 
ruby-1.9.2-p290 :083 > fam.children.build(:name => "Billy Jones")
 => #<Child id: nil, family_id: nil, name: "Billy Jones", gender: nil, birth_date: nil, desired_start_date: nil, application_date: nil, notes: nil, custom1: nil, custom2: nil, custom3: nil, custom4: nil, created_at: nil, updated_at: nil> 
ruby-1.9.2-p290 :084 > fam.parents.build(:name => "Mister Jones")
 => #<Parent id: nil, family_id: nil, name: "Mister Jones", address: nil, phone: nil, email: nil, notes: nil, created_at: nil, updated_at: nil> 
ruby-1.9.2-p290 :085 > fam.save!
ActiveRecord::RecordInvalid: Validation failed: Parents family can't be blank
    from /Users/business/.rvm/gems/ruby-1.9.2-p290@rails311/gems/activerecord-3.1.1/lib/active_record/validations.rb:56:in `save!'
    from /Users/business/.rvm/gems/ruby-1.9.2-p290@rails311/gems/activerecord-3.1.1/lib/active_record/attribute_methods/dirty.rb:33:in `save!'
    from /Users/business/.rvm/gems/ruby-1.9.2-p290@rails311/gems/activerecord-3.1.1/lib/active_record/transactions.rb:246:in `block in save!'
    from /Users/business/.rvm/gems/ruby-1.9.2-p290@rails311/gems/activerecord-3.1.1/lib/active_record/transactions.rb:295:in `block in with_transaction_returning_status'
    from /Users/business/.rvm/gems/ruby-1.9.2-p290@rails311/gems/activerecord-3.1.1/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
    from /Users/business/.rvm/gems/ruby-1.9.2-p290@rails311/gems/activerecord-3.1.1/lib/active_record/transactions.rb:208:in `transaction'
    from /Users/business/.rvm/gems/ruby-1.9.2-p290@rails311/gems/activerecord-3.1.1/lib/active_record/transactions.rb:293:in `with_transaction_returning_status'
    from /Users/business/.rvm/gems/ruby-1.9.2-p290@rails311/gems/activerecord-3.1.1/lib/active_record/transactions.rb:246:in `save!'
    from (irb):85
    from /Users/business/.rvm/gems/ruby-1.9.2-p290@rails311/gems/railties-3.1.1/lib/rails/commands/console.rb:45:in `start'
    from /Users/business/.rvm/gems/ruby-1.9.2-p290@rails311/gems/railties-3.1.1/lib/rails/commands/console.rb:8:in `start'
    from /Users/business/.rvm/gems/ruby-1.9.2-p290@rails311/gems/railties-3.1.1/lib/rails/commands.rb:40:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'
ruby-1.9.2-p290 :086 > 

我会以同样的方式理解它,至少在最初阅读您所拥有的代码时。

也许你可以试试这个替代方案:

http://forums.pragprog.com/forums/74/topics/732

删除

validates_associated   :family 
validates_presence_of  :family_id

and try this

validates_presence_of  :family

最新更新