Szyny - czy potwierdzają obecność stowarzyszenia?

107

Mam model A, który ma powiązanie „has_many” z innym modelem B. Mam wymóg biznesowy, że wstawianie do A wymaga co najmniej 1 rekordu skojarzonego z B. Czy istnieje metoda, którą mogę wywołać, aby upewnić się, że to prawda? czy muszę napisać niestandardową walidację?

skaz
źródło

Odpowiedzi:

167

Możesz użyć 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

lub po prostu validates http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates

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

Ale jest z nim błąd, jeśli będziesz używać accepts_nested_attributes_forz :allow_destroy => true: Modelami zagnieżdżonymi i walidacją nadrzędną . W tym temacie możesz znaleźć rozwiązanie.

fl00r
źródło
18

-------- Szyny 4 ------------

Prosty validates presencedziałał dla mnie

class Profile < ActiveRecord::Base
  belongs_to :user

  validates :user, presence: true
end

class User < ActiveRecord::Base
  has_one :profile
end

W ten sposób Profile.createzakończy się niepowodzeniem. Muszę użyć user.create_profilelub skojarzyć użytkownika przed zapisaniem pliku profile.

hexinpeter
źródło
6

Możesz zweryfikować powiązania za pomocą validates_existence_of(która jest wtyczką):

Przykładowy fragment z tego wpisu na blogu :

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

Alternatywnie możesz użyć validates_associated. Jak zauważa Faisal w komentarzach pod odpowiedzią, validates_associatedsprawdza, czy powiązany obiekt jest prawidłowy, uruchamiając walidację skojarzonej klasy. To ma nie sprawdzić obecność. Ważne jest również, aby pamiętać, że zerowe powiązanie jest uważane za ważne.

Spyros
źródło
4

Jeśli chcesz mieć pewność, że skojarzenie jest obecne i gwarantowane, że będzie ważne, również musisz użyć

class Transaction < ActiveRecord::Base
  belongs_to :bank

  validates_associated :bank
  validates :bank, presence: true
end
Sukeerthi Adiga
źródło
Czy nie byłoby miło, gdybyś mógł przekazać dodatkową opcję validatespolubienia valid: truezamiast dzwonić validates_associatedosobno.
Joshua Pinter