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