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?

skaz
  • 21,962
  • 20
  • 69
  • 98

4 Answers4

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.

Dorian
  • 22,759
  • 8
  • 120
  • 116
fl00r
  • 82,987
  • 33
  • 217
  • 237
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.

hexinpeter
  • 1,470
  • 1
  • 16
  • 14
7

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
Sukeerthi Adiga
  • 531
  • 5
  • 9
  • 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. – Joshua Pinter Jul 21 '18 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.

Community
  • 1
  • 1
Spyros
  • 46,820
  • 25
  • 86
  • 129