views:

66

answers:

2
Account < AR
  has_many :deposits
  accepts_nested_attributes_for :deposits
  attr_accessible :max_amount
end

Deposit < AR
  belongs_to :account
  attr_accessible :amount

  validate :validates_amount_less_than_max_amount

  def validates_amount_less_than_max_amount
    # How do you write this method?  When an Account is being created with a nested 
    # Deposit, it should do this validation, but account is nil until 
    # saved, so @contribution can't access the :max_amount and validate from it.
    # Solution?
  end
end
A: 

Use this validation, as expected:

def validates_amount_less_than_max_amount
  errors.add(:amount, 'is more than max amount') if self.amount > account.max_amount
end

But you can't use new to create the Account and Deposit at the same time, as you noted above. Try wrapping create Account/Deposits in a transaction:

>> Account.transaction do
>> a = Account.create!({:max_amount => 1000})
>> a.deposits_attributes = [{:amount => 1500}]
>> a.save!
>> end
ActiveRecord::RecordInvalid: Validation failed: Deposits amount is more than max amount

See what's new in edge rails 2.3 for more examples.

Jonathan Julian
Yes, this will work but isn't there a way to move this into the models?
Gavin
Absolutely. That's just an irb session; move it into `Account.create_with_deposit!(attributes)`.
Jonathan Julian
A: 

Here's the answer:

https://rails.lighthouseapp.com/projects/8994/tickets/2815-nested-models-build-should-directly-assign-the-parent

The patch is scheduled for 2.3.5. If you want the functionality now, you'll have to apply it and its dependencies.

Gavin