From 65f75b9200c163f7085021e8c0b46342236ac46a Mon Sep 17 00:00:00 2001 From: Caleb Land Date: Mon, 31 May 2010 14:25:56 -0400 Subject: [PATCH] allow spaces in attribute names [#4725 state:resolved] * define the dynamically defined methods with 'define_method' instead of def * wrap some string injected method names in quotes --- activemodel/lib/active_model/attribute_methods.rb | 10 ++++---- activemodel/test/cases/attribute_methods_test.rb | 23 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index 9bacc2a..d89a5fd 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -222,8 +222,8 @@ module ActiveModel def alias_attribute(new_name, old_name) attribute_method_matchers.each do |matcher| module_eval <<-STR, __FILE__, __LINE__ + 1 - def #{matcher.method_name(new_name)}(*args) - send(:#{matcher.method_name(old_name)}, *args) + define_method :'#{matcher.method_name(new_name)}' do |*args| + send(:'#{matcher.method_name(old_name)}', *args) end STR end @@ -266,10 +266,10 @@ module ActiveModel method_name = matcher.method_name(attr_name) generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 - if method_defined?(:#{method_name}) - undef :#{method_name} + if method_defined?(:'#{method_name}') + undef :'#{method_name}' end - def #{method_name}(*args) + define_method(:'#{method_name}') do |*args| send(:#{matcher.method_missing_target}, '#{attr_name}', *args) end STR diff --git a/activemodel/test/cases/attribute_methods_test.rb b/activemodel/test/cases/attribute_methods_test.rb index c60caf9..aa24748 100644 --- a/activemodel/test/cases/attribute_methods_test.rb +++ b/activemodel/test/cases/attribute_methods_test.rb @@ -21,6 +21,21 @@ class ModelWithAttributes2 attribute_method_suffix '_test' end +class ModelWithAttributesWithSpaces + include ActiveModel::AttributeMethods + + attribute_method_suffix '' + + def attributes + { :'foo bar' => 'value of foo bar'} + end + +private + def attribute(name) + attributes[name.to_sym] + end +end + class AttributeMethodsTest < ActiveModel::TestCase test 'unrelated classes should not share attribute method matchers' do assert_not_equal ModelWithAttributes.send(:attribute_method_matchers), @@ -35,6 +50,14 @@ class AttributeMethodsTest < ActiveModel::TestCase assert_equal "value of foo", ModelWithAttributes.new.foo end + 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 + test '#undefine_attribute_methods removes attribute methods' do ModelWithAttributes.define_attribute_methods([:foo]) ModelWithAttributes.undefine_attribute_methods -- 1.7.0.4