From acf0688fdd85a6d6ac278446e81f365239acc198 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 27 Feb 2011 21:14:11 -0200 Subject: failing test for i18n key collision with namespaced models --- activemodel/test/cases/translation_test.rb | 7 +++++++ activemodel/test/models/person.rb | 4 ++++ 2 files changed, 11 insertions(+) (limited to 'activemodel') diff --git a/activemodel/test/cases/translation_test.rb b/activemodel/test/cases/translation_test.rb index c299d6eb5e..1b1d972d5c 100644 --- a/activemodel/test/cases/translation_test.rb +++ b/activemodel/test/cases/translation_test.rb @@ -49,6 +49,13 @@ class ActiveModelI18nTests < ActiveModel::TestCase assert_equal 'person name attribute', Child.human_attribute_name('name') end + def test_translated_model_attributes_with_attribute_matching_namespaced_model_name + I18n.backend.store_translations 'en', :activemodel => {:attributes => {:person => {:gender => 'person gender'}, :"person/gender" => {:attribute => 'person gender attribute'}}} + + assert_equal 'person gender', Person.human_attribute_name('gender') + assert_equal 'person gender attribute', Person::Gender.human_attribute_name('attribute') + end + def test_translated_model_names I18n.backend.store_translations 'en', :activemodel => {:models => {:person => 'person model'} } assert_equal 'person model', Person.model_name.human diff --git a/activemodel/test/models/person.rb b/activemodel/test/models/person.rb index eb84f7a27d..7b7e8feebc 100644 --- a/activemodel/test/models/person.rb +++ b/activemodel/test/models/person.rb @@ -9,6 +9,10 @@ class Person end end +class Person::Gender + extend ActiveModel::Translation +end + class Child < Person end -- cgit v1.2.3 From a00bed0c48f469d1cd2de364bfaddbc724046195 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 27 Feb 2011 21:23:59 -0200 Subject: Revert "Properly interpolate i18n keys in modules [#5572 state:resolved]" This breaks #6448, you should use :"module/class" as key for namespacing [#6448 state:committed] This reverts commit 8d30193b08bd2321a7a78a1f481bd5e4d4d45557. --- activemodel/lib/active_model/errors.rb | 4 ++-- activemodel/lib/active_model/naming.rb | 15 +++++---------- activemodel/lib/active_model/translation.rb | 2 +- .../test/cases/validations/i18n_validation_test.rb | 19 ------------------- activemodel/test/models/person.rb | 5 ----- 5 files changed, 8 insertions(+), 37 deletions(-) (limited to 'activemodel') diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index 5e3cf510b0..c2f0228785 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -295,8 +295,8 @@ module ActiveModel type = options.delete(:message) if options[:message].is_a?(Symbol) defaults = @base.class.lookup_ancestors.map do |klass| - [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}", - :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.#{type}" ] + [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.attributes.#{attribute}.#{type}", + :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.#{type}" ] end defaults << options.delete(:message) diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb index 3f430f94a6..eb9b847509 100644 --- a/activemodel/lib/active_model/naming.rb +++ b/activemodel/lib/active_model/naming.rb @@ -4,7 +4,7 @@ require 'active_support/core_ext/module/introspection' module ActiveModel class Name < String - attr_reader :singular, :plural, :element, :collection, :partial_path, :route_key, :param_key, :i18n_key + attr_reader :singular, :plural, :element, :collection, :partial_path, :route_key, :param_key alias_method :cache_key, :collection def initialize(klass, namespace = nil) @@ -20,7 +20,6 @@ module ActiveModel @partial_path = "#{@collection}/#{@element}".freeze @param_key = (namespace ? _singularize(@unnamespaced) : @singular).freeze @route_key = (namespace ? ActiveSupport::Inflector.pluralize(@param_key) : @plural).freeze - @i18n_key = _singularize(self, '.').to_sym end # Transform the model name into a more humane format, using I18n. By default, @@ -34,7 +33,7 @@ module ActiveModel @klass.respond_to?(:i18n_scope) defaults = @klass.lookup_ancestors.map do |klass| - klass.model_name.i18n_key + klass.model_name.underscore.to_sym end defaults << options[:default] if options[:default] @@ -45,10 +44,9 @@ module ActiveModel end private - - def _singularize(string, replacement='_') - ActiveSupport::Inflector.underscore(string).tr('/', replacement) - end + def _singularize(str) + ActiveSupport::Inflector.underscore(str).tr('/', '_') + end end # == Active Model Naming @@ -64,9 +62,6 @@ module ActiveModel # BookCover.model_name # => "BookCover" # BookCover.model_name.human # => "Book cover" # - # BookCover.model_name.i18n_key # => "book_cover" - # BookModule::BookCover.model_name.i18n_key # => "book_module.book_cover" - # # Providing the functionality that ActiveModel::Naming provides in your object # is required to pass the Active Model Lint test. So either extending the provided # method below, or rolling your own is required. diff --git a/activemodel/lib/active_model/translation.rb b/activemodel/lib/active_model/translation.rb index 920a133159..dbb76244e4 100644 --- a/activemodel/lib/active_model/translation.rb +++ b/activemodel/lib/active_model/translation.rb @@ -44,7 +44,7 @@ module ActiveModel # Specify +options+ with additional translating options. def human_attribute_name(attribute, options = {}) defaults = lookup_ancestors.map do |klass| - :"#{self.i18n_scope}.attributes.#{klass.model_name.i18n_key}.#{attribute}" + :"#{self.i18n_scope}.attributes.#{klass.model_name.underscore}.#{attribute}" end defaults << :"attributes.#{attribute}" diff --git a/activemodel/test/cases/validations/i18n_validation_test.rb b/activemodel/test/cases/validations/i18n_validation_test.rb index 5cb7bff4e7..e9f0e430fe 100644 --- a/activemodel/test/cases/validations/i18n_validation_test.rb +++ b/activemodel/test/cases/validations/i18n_validation_test.rb @@ -55,14 +55,6 @@ class I18nValidationTest < ActiveModel::TestCase assert_equal ["Person's name not found"], @person.errors.full_messages end - def test_errors_full_messages_translates_human_attribute_name_for_model_in_module_attributes - I18n.backend.store_translations('en', :activemodel => {:attributes => {:person_module => {:person => {:name => "Person in Module's name"}}}}) - person = PersonModule::Person.new - person.errors.add(:name, 'not found') - PersonModule::Person.expects(:human_attribute_name).with(:name, :default => 'Name').returns("Person in Module's name") - assert_equal ["Person in Module's name not found"], person.errors.full_messages - end - def test_errors_full_messages_uses_format I18n.backend.store_translations('en', :errors => {:format => "Field %{attribute} %{message}"}) @person.errors.add('name', 'empty') @@ -371,15 +363,4 @@ class I18nValidationTest < ActiveModel::TestCase assert_equal ["I am a custom error"], @person.errors[:title] end - def test_model_with_module_i18n_scope - I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person_module => {:person => {:blank => 'generic blank'}}}}} - PersonModule::Person.validates_presence_of :title - person = PersonModule::Person.new - person.valid? - assert_equal ['generic blank'], person.errors[:title] - - I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person_module => {:person => {:attributes => {:title => {:blank => 'title cannot be blank'}}}}}}} - person.valid? - assert_equal ['title cannot be blank'], person.errors[:title] - end end diff --git a/activemodel/test/models/person.rb b/activemodel/test/models/person.rb index 7b7e8feebc..e896e90f98 100644 --- a/activemodel/test/models/person.rb +++ b/activemodel/test/models/person.rb @@ -15,8 +15,3 @@ end class Child < Person end - -module PersonModule - class Person < ::Person - end -end -- cgit v1.2.3 From 24faddd60c5fd148c8264898aeca2d5f36b25a4b Mon Sep 17 00:00:00 2001 From: Alexander Uvarov Date: Sun, 13 Feb 2011 22:27:33 +0500 Subject: Move ActiveModel::AttributeMethods#attribute_methods_generated? to ActiveRecord, so it's flexible now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#6428 state:resolved] Signed-off-by: José Valim --- activemodel/CHANGELOG | 2 ++ activemodel/lib/active_model/attribute_methods.rb | 44 ++++++++++------------- activemodel/test/cases/attribute_methods_test.rb | 10 ++++-- 3 files changed, 28 insertions(+), 28 deletions(-) (limited to 'activemodel') diff --git a/activemodel/CHANGELOG b/activemodel/CHANGELOG index 9dd5e03685..3082c7186a 100644 --- a/activemodel/CHANGELOG +++ b/activemodel/CHANGELOG @@ -2,6 +2,8 @@ * Added ActiveModel::SecurePassword to encapsulate dead-simple password usage with BCrypt encryption and salting [DHH] +* ActiveModel::AttributeMethods allows attributes to be defined on demand [Alexander Uvarov] + *Rails 3.0.2 (unreleased)* diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index 8f3782eb48..2a99450a3d 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -260,30 +260,30 @@ module ActiveModel # end # end def define_attribute_methods(attr_names) - return if attribute_methods_generated? - attr_names.each do |attr_name| - attribute_method_matchers.each do |matcher| - unless instance_method_already_implemented?(matcher.method_name(attr_name)) - generate_method = "define_method_#{matcher.prefix}attribute#{matcher.suffix}" + attr_names.each { |attr_name| define_attribute_method(attr_name) } + end + + def define_attribute_method(attr_name) + attribute_method_matchers.each do |matcher| + unless instance_method_already_implemented?(matcher.method_name(attr_name)) + generate_method = "define_method_#{matcher.prefix}attribute#{matcher.suffix}" - if respond_to?(generate_method) - send(generate_method, attr_name) - else - method_name = matcher.method_name(attr_name) + if respond_to?(generate_method) + send(generate_method, attr_name) + else + method_name = matcher.method_name(attr_name) - generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 - if method_defined?('#{method_name}') - undef :'#{method_name}' - end - define_method('#{method_name}') do |*args| - send('#{matcher.method_missing_target}', '#{attr_name}', *args) - end - STR - end + generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 + if method_defined?('#{method_name}') + undef :'#{method_name}' + end + define_method('#{method_name}') do |*args| + send('#{matcher.method_missing_target}', '#{attr_name}', *args) + end + STR end end end - @attribute_methods_generated = true end # Removes all the previously dynamically defined methods from the class @@ -291,7 +291,6 @@ module ActiveModel generated_attribute_methods.module_eval do instance_methods.each { |m| undef_method(m) } end - @attribute_methods_generated = nil end # Returns true if the attribute methods defined have been generated. @@ -303,11 +302,6 @@ module ActiveModel end end - # Returns true if the attribute methods defined have been generated. - def attribute_methods_generated? - @attribute_methods_generated ||= nil - end - protected def instance_method_already_implemented?(method_name) method_defined?(method_name) diff --git a/activemodel/test/cases/attribute_methods_test.rb b/activemodel/test/cases/attribute_methods_test.rb index 422aa25668..b001adb35a 100644 --- a/activemodel/test/cases/attribute_methods_test.rb +++ b/activemodel/test/cases/attribute_methods_test.rb @@ -42,10 +42,16 @@ class AttributeMethodsTest < ActiveModel::TestCase ModelWithAttributes2.send(:attribute_method_matchers) end + test '#define_attribute_method generates attribute method' do + ModelWithAttributes.define_attribute_method(:foo) + + assert_respond_to ModelWithAttributes.new, :foo + assert_equal "value of foo", ModelWithAttributes.new.foo + end + test '#define_attribute_methods generates attribute methods' do ModelWithAttributes.define_attribute_methods([:foo]) - assert ModelWithAttributes.attribute_methods_generated? assert_respond_to ModelWithAttributes.new, :foo assert_equal "value of foo", ModelWithAttributes.new.foo end @@ -53,7 +59,6 @@ class AttributeMethodsTest < ActiveModel::TestCase test '#define_attribute_methods generates attribute methods with spaces in their names' do ModelWithAttributesWithSpaces.define_attribute_methods([:'foo bar']) - assert ModelWithAttributesWithSpaces.attribute_methods_generated? assert_respond_to ModelWithAttributesWithSpaces.new, :'foo bar' assert_equal "value of foo bar", ModelWithAttributesWithSpaces.new.send(:'foo bar') end @@ -69,7 +74,6 @@ class AttributeMethodsTest < ActiveModel::TestCase ModelWithAttributes.define_attribute_methods([:foo]) ModelWithAttributes.undefine_attribute_methods - assert !ModelWithAttributes.attribute_methods_generated? assert !ModelWithAttributes.new.respond_to?(:foo) assert_raises(NoMethodError) { ModelWithAttributes.new.foo } end -- cgit v1.2.3 From 86c15d8b8984b5865d73ecdd6687d91060bda5ba Mon Sep 17 00:00:00 2001 From: "R.T. Lechow" Date: Thu, 3 Mar 2011 22:23:30 -0500 Subject: Active Model typos. --- activemodel/README.rdoc | 2 +- activemodel/test/cases/validations/numericality_validation_test.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'activemodel') diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc index d9a9bdae3e..b5b5edd52a 100644 --- a/activemodel/README.rdoc +++ b/activemodel/README.rdoc @@ -8,7 +8,7 @@ the Rails framework. Prior to Rails 3.0, if a plugin or gem developer wanted to have an object interact with Action Pack helpers, it was required to either copy chunks of code from Rails, or monkey patch entire helpers to make them handle objects -that did not exacly conform to the Active Record interface. This would result +that did not exactly conform to the Active Record interface. This would result in code duplication and fragile applications that broke on upgrades. Active Model solves this. You can include functionality from the following diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb index e1d7d40c47..08f6169ca5 100644 --- a/activemodel/test/cases/validations/numericality_validation_test.rb +++ b/activemodel/test/cases/validations/numericality_validation_test.rb @@ -14,7 +14,7 @@ class NumericalityValidationTest < ActiveModel::TestCase NIL = [nil] BLANK = ["", " ", " \t \r \n"] - BIGDECIMAL_STRINGS = %w(12345678901234567890.1234567890) # 30 significent digits + BIGDECIMAL_STRINGS = %w(12345678901234567890.1234567890) # 30 significant digits FLOAT_STRINGS = %w(0.0 +0.0 -0.0 10.0 10.5 -10.5 -0.0001 -090.1 90.1e1 -90.1e5 -90.1e-5 90e-5) INTEGER_STRINGS = %w(0 +0 -0 10 +10 -10 0090 -090) FLOATS = [0.0, 10.0, 10.5, -10.5, -0.0001] + FLOAT_STRINGS -- cgit v1.2.3