Rails - Validar Presença de Associação?

107

Eu tenho um modelo A que tem uma associação "has_many" a outro modelo B. Tenho um requisito de negócios de que uma inserção em A requer pelo menos 1 registro associado a B. Existe um método que posso chamar para ter certeza de que isso é verdade, ou preciso escrever uma validação personalizada?

Skaz
fonte

Respostas:

167

Você pode usar 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

ou apenas validates http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates

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

Mas há um bug com isso se você usar accepts_nested_attributes_forcom :allow_destroy => true: Modelos aninhados e validação pai . Neste tópico você pode encontrar uma solução.

fl00r
fonte
18

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

Simples validates presencefuncionou para mim

class Profile < ActiveRecord::Base
  belongs_to :user

  validates :user, presence: true
end

class User < ActiveRecord::Base
  has_one :profile
end

Dessa forma, Profile.createagora irá falhar. Tenho que usar user.create_profileou associar um usuário antes de salvar um profile.

hexineter
fonte
6

Você pode validar associações com validates_existence_of (que é um plug-in):

Trecho de exemplo desta entrada de blog :

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

Alternativamente, você pode usar validates_associated. Como Faisal observa nos comentários abaixo da resposta, validates_associatedverifica se o objeto associado é válido executando as validações de classe associadas. Ele não verificar a presença. Também é importante observar que uma associação nula é considerada válida.

Spyros
fonte
4

Se você quiser garantir que a associação esteja presente e seja válida, você também precisa usar

class Transaction < ActiveRecord::Base
  belongs_to :bank

  validates_associated :bank
  validates :bank, presence: true
end
Sukeerthi Adiga
fonte
Não seria bom se você pudesse passar uma opção adicional para validatescurtir em valid: truevez de ter que ligar validates_associatedseparadamente.
Joshua Pinter