111

I have a model A that has a "has_many" association to another model B. I have a business requirement that an insert into A requires at least 1 associated record to B. Is there a method I can call to make sure this is true, or do I need to write a custom validation?

4 Answers 4

175

You can use validates_presence_of http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates_presence_of

class A < ActiveRecord::Base
  has_many :bs
  validates_presence_of :bs
end

or just validates http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates

class A < ActiveRecord::Base
  has_many :bs
  validates :bs, :presence => true
end

But there is a bug with it if you will use accepts_nested_attributes_for with :allow_destroy => true: Nested models and parent validation. In this topic you can find solution.

0
18

-------- Rails 4 ------------

Simple validates presence worked for me

class Profile < ActiveRecord::Base
  belongs_to :user

  validates :user, presence: true
end

class User < ActiveRecord::Base
  has_one :profile
end

This way, Profile.create will now fail. I have to use user.create_profile or associate a user before saving a profile.

8

If you want to ensure that the association is both present and guaranteed to be valid, you also need to use

class Transaction < ActiveRecord::Base
  belongs_to :bank

  validates_associated :bank
  validates :bank, presence: true
end
1
  • Wouldn't it be nice if you could pass an additional option to validates like valid: true instead of having to call validates_associated separately. Commented Jul 21, 2018 at 18:05
6

You can validate associations with validates_existence_of (which is a plugin):

Example snippet from this blog entry:

class Tagging < ActiveRecord::Base
  belongs_to :tag
  belongs_to :taggable, :polymorphic => true
  validates_existence_of :tag, :taggable

  belongs_to :user
  validates_existence_of :user, :allow_nil => true
end

Alternatively, you can use validates_associated. As Faisal notes in the comments below the answer, validates_associated checks if the associated object is valid by running the associated class validations. It does not check for the presence. It's also important to note that a nil association is considered valid.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.