Would this not be the proper solution ?
User has many payments. I want the user to have at
least one payment with an amount, before a user is
valid.
class User < ActiveRecord::Base
default_scope :order => :id
has_many :payments
validate :has_one_complete_payment
private
def has_one_complete_payment
errors.add(:base, :missing_complete_payment) unless payments.detect
{|p| p.amount}
end
end
$ cat config/locales/en.yml
en:
hello: “Hello world”
activerecord:
errors:
models:
user:
attributes:
base:
missing_complete_payment: You need at least one payment
with amount filled out
That results in this behaviour:
$ rails c
Loading development environment (Rails 3.0.3)
001:0> user = User.new(:first_name => “Jon”)
=> #<User id: nil, first_name: “Jon”, last_name: nil, user_name: nil,
testing: nil, created_at: nil, updated_at: nil>
002:0> user.valid?
=> false
003:0> user.errors
=> #<OrderedHash {:base=>[“You need at least one payment with amount
filled out”]}>
004:0> p1 = user.payments.build()
=> #<Payment id: nil, user_id: nil, testing: nil, created_at: nil,
updated_at: nil, amount: nil>
005:0> user.valid?
=> false
006:0> user.errors
=> #<OrderedHash {:base=>[“You need at least one payment with amount
filled out”]}>
007:0> p2 = user.payments.build()
=> #<Payment id: nil, user_id: nil, testing: nil, created_at: nil,
updated_at: nil, amount: nil>
010:0> user.valid?
=> false
011:0> user.errors
=> #<OrderedHash {:base=>[“You need at least one payment with amount
filled out”]}>
012:0> p2.amount = “123.45”
=> “123.45”
013:0> user.valid?
=> true
014:0> user.save
=> true
015:0> user.payments.inspect
=> “[#<Payment id: 1, user_id: 1, testing: nil, created_at: “2010-12-23
21:57:01”, updated_at: “2010-12-23 21:57:01”, amount: nil>, #<Payment
id: 2, user_id: 1, testing: nil, created_at: “2010-12-23 21:57:01”,
updated_at: “2010-12-23 21:57:01”, amount:
#BigDecimal:b6cbb554,‘0.12345E3’,8(12)>]”
015:0>
HTH,
Peter