Rails - ¿Validar la presencia de asociación?

107

Tengo un modelo A que tiene una asociación "has_many" con otro modelo B. Tengo un requisito comercial de que una inserción en A requiere al menos 1 registro asociado a B. ¿Hay algún método al que pueda llamar para asegurarme de que esto sea cierto? ¿O necesito escribir una validación personalizada?

skaz
fuente

Respuestas:

167

Puede utilizar 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

o simplemente validates http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates

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

Pero hay un error si lo usa accepts_nested_attributes_forcon :allow_destroy => true: modelos anidados y validación principal . En este tema puede encontrar una solución.

fl00r
fuente
18

-------- Carriles 4 ------------

Simple validates presencefuncionó para mí

class Profile < ActiveRecord::Base
  belongs_to :user

  validates :user, presence: true
end

class User < ActiveRecord::Base
  has_one :profile
end

De esta manera, Profile.createahora fallará. Tengo que usar user.create_profileo asociar un usuario antes de guardar un archivo profile.

hexinpeter
fuente
6

Puede validar asociaciones con validates_existence_of(que es un complemento):

Fragmento de ejemplo de esta 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, puede usar validates_associated. Como señala Faisal en los comentarios debajo de la respuesta, validates_associatedverifica si el objeto asociado es válido ejecutando las validaciones de clase asociadas. No , no verificar la presencia. También es importante tener en cuenta que una asociación nula se considera válida.

Spyros
fuente
4

Si desea asegurarse de que la asociación está presente y se garantiza que es válida, también debe usar

class Transaction < ActiveRecord::Base
  belongs_to :bank

  validates_associated :bank
  validates :bank, presence: true
end
Sukeerthi Adiga
fuente
¿No sería bueno si pudiera pasar una opción adicional a Me validatesgusta en valid: truelugar de tener que llamar por validates_associatedseparado?
Joshua Pinter