Created
September 11, 2013 16:07
-
-
Save cec/6525812 to your computer and use it in GitHub Desktop.
Rails 3.2 - Custom validator class on parent model, clashing with validates_associated :child_models
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
class Event < ActiveRecord::Base | |
include LocalizedTexts | |
has_many :texts, :class_name => 'EventText', :dependent => :destroy, :inverse_of => :event | |
validates_with MultiTextValidator | |
validates_associated :texts | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#encoding: utf-8 | |
class EventText < ActiveRecord::Base | |
belongs_to :event, inverse_of: :texts | |
validates_presence_of :title, :intro | |
validate :pricing_details | |
private | |
def pricing_details | |
unless event.free? ^ pricing.present? | |
msg = pricing.present?() ? "error_message_1" : "error_message_2" | |
errors[:pricing] << msg | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: UTF-8 | |
# This validator checks common validation rules for all models having associated text models | |
class MultiTextValidator < ActiveModel::Validator | |
cattr_reader :error_messages | |
@@error_messages = { | |
italian_missing: 'activemodel.errors.event.texts.italian_missing', | |
non_unique_languages: 'activemodel.errors.event.texts.non_unique_languages', | |
} | |
def validate record | |
italian_required record | |
unique_languages record | |
end | |
private | |
def italian_required record | |
unless record.texts.find { |t| t.language == :it } | |
message = I18n.t self.class.error_messages[:italian_missing] | |
record.errors.add :base, message | |
record.errors.add :texts, message | |
record.texts.last.errors.add(:language, message) unless record.texts.empty? | |
end | |
end | |
def unique_languages record | |
languages = record.texts.map(&:language) | |
return if languages.uniq.length == languages.length | |
counts = {} | |
languages.uniq.each { |l| counts[l] = ( record.texts.to_a.count {|text| text.language == l} ) } | |
counts.delete_if { |k, v| v == 1 } | |
non_unique_languages = counts.keys | |
non_unique_languages.each do |lang| | |
message = I18n.t(self.class.error_messages[:non_unique_languages], language: lang) | |
record.errors.add :base, message | |
record.texts.each do |t| | |
t.errors.add(:language, message) if t.language == lang | |
end | |
end | |
end | |
# Association Reflection Fancyness | |
def supported_languages record | |
record.class.reflect_on_association(:texts).options[:class_name].constantize::LANGUAGES | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment