From b5ee1673de7a3d872f0e356b6a2b6ef341afcf44 Mon Sep 17 00:00:00 2001 From: Caleb Land Date: Tue, 1 Jun 2010 19:24:52 -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 | 22 ++++++--------- activemodel/test/cases/attribute_methods_test.rb | 30 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index 9bacc2a..8329018 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -221,11 +221,9 @@ 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) - end - STR + define_method matcher.method_name(new_name).to_sym do |*args| + send(matcher.method_name(old_name).to_sym, *args) + end end end @@ -265,14 +263,12 @@ module ActiveModel 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 - def #{method_name}(*args) - send(:#{matcher.method_missing_target}, '#{attr_name}', *args) - end - STR + if generated_attribute_methods.method_defined?(method_name.to_sym) + generated_attribute_methods.send(:undef_method, method_name.to_sym) + end + generated_attribute_methods.send(:define_method, method_name.to_sym) do |*args| + send(matcher.method_missing_target.to_sym, attr_name, *args) + end end end end diff --git a/activemodel/test/cases/attribute_methods_test.rb b/activemodel/test/cases/attribute_methods_test.rb index c60caf9..c2d8061 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.1