One form, multiple models, custom validation

Hi everyone,

I hope someone can help me solve this problem. I have a model called Project with :has_many => :tasks. In the new Project form i allow the creation of 1 to n tasks on the fly thanks to accepts_nested_attributes_for, where the task model has some validations that block the creation of the new project if the required fields are not correct.

This works just fine as it is supposed to work, but here's the problem:

At least one task needs to have some fields not empty, otherwise the project should not be created. It can be any of the tasks but it's imperative that at least one of them has those attributes, for the other tasks these attributes are not required. Is there a way of doing that without strange hacks?

Thanks in advance for your help

Hi Serafino,

I am assuming that you are using Javascript. If that is the case, then you can find the solution here Unobtrusive dynamic form fields in Rails with jQuery - Stack Overflow

All the best,

Fidel.

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