Skip to content

Instantly share code, notes, and snippets.

@kml
Last active December 13, 2016 20:34
Show Gist options
  • Save kml/d7a0f27fe0c7c477f2f6 to your computer and use it in GitHub Desktop.
Save kml/d7a0f27fe0c7c477f2f6 to your computer and use it in GitHub Desktop.
ActiveModel::Model - show nested errors
class PersonData
include ActiveModel::Model
include Virtus.model
attribute :pesel, String
attribute :id_type, String
validates :pesel, presence: true
validates :id_type, presence: true
end
class CompanyData
include ActiveModel::Model
include Virtus.model
attribute :name, String
attribute :nip, String
validates :name, presence: true
validates :nip, presence: true
end
class Partner
include ActiveModel::Model
include Virtus.model
attribute :test
attribute :person_data, PersonData
attribute :company_data, CompanyData
# decyduje, czy company_data będzie walidowane
attribute :check_company, Boolean, default: false
validates :test, presence: true
# zawsze uruchamiane przy valid?
# na podstawie pierwszego komentarza z http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validates_associated
validate do
[:person_data].each do |attr|
errors.add(attr, :invalid) if send(attr) && send(attr).invalid?
end
end
# warunkowa walidacja
# ":if - Specifies a method, proc or string to call to determine
# if the validation should occur (e.g. if: :allow_validation,
# or if: Proc.new { |user| user.signup_step > 2 }).
# The method, proc or string should return or evaluate to a true or false value."
validate :validate_company, if: :check_company
private
def validate_company
errors.add(:company_data, :invalid) if company_data.nil? || company_data.invalid?
end
end
p = Partner.new(person_data: {pesel: 123})
p.valid?
# => false
p.errors.full_messages
# => ["Test nie może być puste", "Person data jest nieprawidłowe"]
p = Partner.new(check_company: true, company_data: {nip: -1})
p.valid?
# => false
p.errors.full_messages
# => ["Test nie może być puste", "Company data jest nieprawidłowe"]
if p.errors.any?
p.errors.full_messages.each do |message|
puts message
end
end
# ->
if p.errors.any?
p.errors.each do |attribute, message|
puts p.errors.full_message(attribute, message)
end
end
# ->
if p.errors.any?
p.errors.each do |attribute, message|
if p.send(attribute).respond_to?(:errors)
p.send(attribute).errors.full_messages.each do |m|
puts "#{attribute} (#{p.errors.full_message(attribute, '').strip}) - #{m}"
end
else
puts p.errors.full_message(attribute, message)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment