Rails - подтверждение присутствия ассоциации?

У меня есть модель A, которая имеет ассоциацию has_many с другой моделью B. У меня есть бизнес-требование, что для вставки в требуется по меньшей мере одна связанная запись с B. Существует ли способ, который я могу вызвать, чтобы убедиться, что это true, или мне нужно написать пользовательскую проверку?

Ответ 1

Вы можете использовать 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

или просто validates http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates

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

Но есть ошибка, если вы будете использовать accepts_nested_attributes_for с :allow_destroy => true: Вложенные модели и родительскую проверку. В этом разделе вы можете найти решение.

Ответ 2

-------- Рельсы 4 ------------

Простой validates presence работал у меня

class Profile < ActiveRecord::Base
  belongs_to :user

  validates :user, presence: true
end

class User < ActiveRecord::Base
  has_one :profile
end

Таким образом, Profile.create будет терпеть неудачу. Я должен использовать user.create_profile или связать пользователя перед сохранением profile.

Ответ 3

Вы можете проверить ассоциации с validates_existence_of (который является плагином):

Пример фрагмента из этой записи в блоге:

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

В качестве альтернативы вы можете использовать validates_associated. Как примечания Фейсала в комментариях ниже ответа validates_associated проверяет, является ли связанный объект действительным, запустив связанные проверки класса. Он проверяет наличие не. Важно также отметить, что ассоциация ниль считается действительной.

Ответ 4

Если вы хотите убедиться, что ассоциация присутствует и гарантирована как действительная, вам также необходимо использовать

class Transaction < ActiveRecord::Base
  belongs_to :bank

  validates_associated :bank
  validates :bank, presence: true
end