From 3cf74ad011d750fdd897cd5080fe6ea43c136cfd Mon Sep 17 00:00:00 2001 From: Caleb Land Date: Thu, 3 Feb 2011 13:46:03 -0500 Subject: [PATCH] allow spaces and other characters 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 | 8 +++--- activemodel/test/cases/attribute_methods_test.rb | 30 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index 34669c1..f46fa3a 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -230,8 +230,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 @@ -277,8 +277,8 @@ module ActiveModel if method_defined?(:'#{method_name}') undef :'#{method_name}' end - def #{method_name}(*args) - send(:#{matcher.method_missing_target}, '#{attr_name}', *args) + define_method(:'#{method_name}') do |*args| + send(:'#{matcher.method_missing_target}', '#{attr_name}', *args) end STR end diff --git a/activemodel/test/cases/attribute_methods_test.rb b/activemodel/test/cases/attribute_methods_test.rb index 54cf838..422aa25 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,21 @@ 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 '#alias_attribute works with attributes with spaces in their names' do + ModelWithAttributesWithSpaces.define_attribute_methods([:'foo bar']) + ModelWithAttributesWithSpaces.alias_attribute(:'foo_bar', :'foo bar') + + assert_equal "value of foo bar", ModelWithAttributesWithSpaces.new.foo_bar + end + test '#undefine_attribute_methods removes attribute methods' do ModelWithAttributes.define_attribute_methods([:foo]) ModelWithAttributes.undefine_attribute_methods -- 1.7.3.5