From 5cd0e3fc728e76e88856e9dbec8d34639883924e Mon Sep 17 00:00:00 2001 From: Kieran Pilkington Date: Fri, 20 Nov 2009 10:10:35 +1300 Subject: [PATCH] Adding lambda support to validates_* Rails methods, to parse at runtime, not when the application loads. This gets around two issues, where {{t. functionality wasn't available in models at that point, and where strings were forzen as whatever language the app booted as. --- app/models/choice.rb | 4 ++-- app/models/extended_field.rb | 6 +++--- app/models/import.rb | 4 ++-- app/models/oai_pmh_repository_set.rb | 2 +- app/models/topic_type.rb | 2 +- app/models/user.rb | 4 ++-- vendor/rails/activerecord/lib/active_record/validations.rb | 5 +++++ 7 files changed, 16 insertions(+), 11 deletions(-) diff --git a/app/models/choice.rb b/app/models/choice.rb index 8da227e7f..f1d7ce9c0 100644 --- a/app/models/choice.rb +++ b/app/models/choice.rb @@ -32,8 +32,8 @@ class Choice < ActiveRecord::Base validates_presence_of :value # Label and value must be unique (for lookup reasons) - validates_uniqueness_of :label, :message => I18n.t('choice_model.must_be_unique') - validates_uniqueness_of :value, :message => I18n.t('choice_model.must_be_unique') + validates_uniqueness_of :label, :message => lambda { I18n.t('choice_model.must_be_unique') } + validates_uniqueness_of :value, :message => lambda { I18n.t('choice_model.must_be_unique') } # class methods class << self diff --git a/app/models/extended_field.rb b/app/models/extended_field.rb index 25858a519..8ad32706d 100755 --- a/app/models/extended_field.rb +++ b/app/models/extended_field.rb @@ -68,16 +68,16 @@ def pseudo_choices=(array_of_ids) validates_uniqueness_of :label, :case_sensitive => false # don't allow special characters in label that will break our xml - validates_format_of :label, :with => /^[^\'\":<>\&,\/\\\?\.]*$/, :message => I18n.t('extended_field_model.invalid_chars', :invalid_chars => ": \', \\, /, &, \", ?, <, >, and .") + validates_format_of :label, :with => /^[^\'\":<>\&,\/\\\?\.]*$/, :message => lambda { I18n.t('extended_field_model.invalid_chars', :invalid_chars => ": \', \\, /, &, \", ?, <, >, and .") } # don't allow spaces - validates_format_of :xml_element_name, :xsi_type, :with => /^[^\s]*$/, :message => I18n.t('extended_field_model.no_spaces') + validates_format_of :xml_element_name, :xsi_type, :with => /^[^\s]*$/, :message => lambda { I18n.t('extended_field_model.no_spaces') } # TODO: add validation that prevents adding xsi_type without xml_element_name # don't allow topic or content base attributes: title, description invalid_label_names = TopicType.column_names + ContentType.column_names - validates_exclusion_of :label, :in => invalid_label_names, :message => I18n.t('extended_field_model.already_used', :invalid_label_names => invalid_label_names.join(", ")) + validates_exclusion_of :label, :in => invalid_label_names, :message => lambda { I18n.t('extended_field_model.already_used', :invalid_label_names => invalid_label_names.join(", ")) } # TODO: globalize stuff, uncomment later # translates :label, :description diff --git a/app/models/import.rb b/app/models/import.rb index d93885209..bd6cc868a 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -15,8 +15,8 @@ class Import < ActiveRecord::Base validates_presence_of :xml_type, :interval_between_records # don't allow special characters in directory name that will break our import - validates_format_of :directory, :with => /^[^ \'\"<>\&,\/\\\?]*$/, :message => I18n.t('import_model.invalid_chars', :invalid_chars => "spaces and \', \\, /, &, \", ?, <, and >") - validates_numericality_of :interval_between_records, :only_integer => true, :message => I18n.t('import_model.must_be_seconds') + validates_format_of :directory, :with => /^[^ \'\"<>\&,\/\\\?]*$/, :message => lambda { I18n.t('import_model.invalid_chars', :invalid_chars => "spaces and \', \\, /, &, \", ?, <, and >") } + validates_numericality_of :interval_between_records, :only_integer => true, :message => lambda { I18n.t('import_model.must_be_seconds') } # HACK -- directory appears to have become a reserved word in some context # and as a result is a private method diff --git a/app/models/oai_pmh_repository_set.rb b/app/models/oai_pmh_repository_set.rb index 6adfc5269..8b3d2b8e6 100644 --- a/app/models/oai_pmh_repository_set.rb +++ b/app/models/oai_pmh_repository_set.rb @@ -22,7 +22,7 @@ class OaiPmhRepositorySet < ActiveRecord::Base # don't allow special characters in name or set_spec that will break our xml validates_format_of :name, :set_spec, :with => /^[^\'\":<>\&,\/\\\?]*$/, - :message => I18n.t('oai_pmh_repository_set_model.invalid_chars', :invalid_chars => "\', \\, /, &, \", ?, <, and >") + :message => lambda { I18n.t('oai_pmh_repository_set_model.invalid_chars', :invalid_chars => "\', \\, /, &, \", ?, <, and >") } class GeneratedSet attr_accessor :name, :description, :spec diff --git a/app/models/topic_type.rb b/app/models/topic_type.rb index bddcfdce6..98198e389 100644 --- a/app/models/topic_type.rb +++ b/app/models/topic_type.rb @@ -30,7 +30,7 @@ def <<(required_form_field) validates_uniqueness_of :name, :case_sensitive => false # don't allow special characters in label that will break urls - validates_format_of :name, :with => /^[^\'\":<>\&,\/\\\?\.]*$/, :message => I18n.t('topic_type_model.invalid_chars', :invalid_chars => ": \', \\, /, &, \", ?, <, >, and .") + validates_format_of :name, :with => /^[^\'\":<>\&,\/\\\?\.]*$/, :message => lambda { I18n.t('topic_type_model.invalid_chars', :invalid_chars => ": \', \\, /, &, \", ?, <, >, and .") } # to support inheritance of fields from ancestor topic types acts_as_nested_set diff --git a/app/models/user.rb b/app/models/user.rb index f9239742f..da3d5df41 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -88,7 +88,7 @@ class User < ActiveRecord::Base validates_confirmation_of :password, :if => :password_required? # Walter McGinnis, 2008-03-16 # refining captcha to be more accessable (i.e. adding questions) and also make more sense to end user - validates_confirmation_of :security_code, :if => :new_record?, :message => I18n.t('user_model.failed_security_answer') + validates_confirmation_of :security_code, :if => :new_record?, :message => lambda { I18n.t('user_model.failed_security_answer') } validates_length_of :login, :within => 3..40 validates_length_of :email, :within => 3..100 validates_format_of :login, :with => /^[^\s]+$/ @@ -96,7 +96,7 @@ class User < ActiveRecord::Base cattr_accessor :locale_choices @@locale_choices ||= YAML.load(IO.read(File.join(RAILS_ROOT, 'config/locales.yml'))) - validates_inclusion_of :locale, :in => @@locale_choices.keys, :message => I18n.t('user_model.locale_incorrect', :locales => @@locale_choices.keys.join(', ')) + validates_inclusion_of :locale, :in => @@locale_choices.keys, :message => lambda { I18n.t('user_model.locale_incorrect', :locales => @@locale_choices.keys.join(', ')) } before_save :encrypt_password diff --git a/vendor/rails/activerecord/lib/active_record/validations.rb b/vendor/rails/activerecord/lib/active_record/validations.rb index b339f0c56..442328883 100644 --- a/vendor/rails/activerecord/lib/active_record/validations.rb +++ b/vendor/rails/activerecord/lib/active_record/validations.rb @@ -161,6 +161,11 @@ def add(error_or_attr, message = nil, options = {}) error, attribute = error_or_attr.is_a?(Error) ? [error_or_attr, error_or_attr.attribute] : [nil, error_or_attr] options[:message] = options.delete(:default) if options.has_key?(:default) + # Kieran Pilkington, 2009-11-20 + # Adding support for wrapping messages in lambdas, + # to parse at run time, not when the application boots + options[:message] = options[:message].call if options[:message].is_a?(Proc) + @errors[attribute.to_s] ||= [] @errors[attribute.to_s] << (error || Error.new(@base, attribute, message, options)) end