Rails - проверка наличия ассоциации?


108

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

Ответы:


168

Вы можете использовать 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: Вложенными моделями и родительской проверкой . В этой теме вы можете найти решение.


18

-------- Рельсы 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.


6

Вы можете проверить ассоциации с помощью 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

Было бы неплохо, если бы вы могли передать дополнительную опцию, которая validatesпонравится, valid: trueвместо того, чтобы звонить validates_associatedотдельно.
Джошуа Пинтер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.