Skip to content
This repository
Browse code

Sync attribute_methods.rb with master code, tests added

[#6580 state:committed]
  • Loading branch information...
commit 691530a19d1b335b6e8bc9f4c20c96124625acbe 1 parent 665065c
Santiago Pastorino authored March 17, 2011
13  activemodel/lib/active_model/attribute_methods.rb
@@ -101,11 +101,8 @@ def define_attr_method(name, value=nil, &block)
101 101
         if block_given?
102 102
           sing.send :define_method, name, &block
103 103
         else
104  
-          # use eval instead of a block to work around a memory leak in dev
105  
-          # mode in fcgi
106  
-          sing.class_eval <<-eorb, __FILE__, __LINE__ + 1
107  
-            def #{name}; #{value.to_s.inspect}; end
108  
-          eorb
  104
+          value = value.to_s if value
  105
+          sing.send(:define_method, name) { value && value.dup }
109 106
         end
110 107
       end
111 108
 
@@ -226,7 +223,7 @@ def alias_attribute(new_name, old_name)
226 223
         attribute_method_matchers.each do |matcher|
227 224
           module_eval <<-STR, __FILE__, __LINE__ + 1
228 225
             def #{matcher.method_name(new_name)}(*args)
229  
-              send(:#{matcher.method_name(old_name)}, *args)
  226
+              send(:'#{matcher.method_name(old_name)}', *args)
230 227
             end
231 228
           STR
232 229
         end
@@ -272,8 +269,8 @@ def define_attribute_methods(attr_names)
272 269
                   if method_defined?(:'#{method_name}')
273 270
                     undef :'#{method_name}'
274 271
                   end
275  
-                  def #{method_name}(*args)
276  
-                    send(:#{matcher.method_missing_target}, '#{attr_name}', *args)
  272
+                  define_method('#{method_name}') do |*args|
  273
+                    send(:'#{matcher.method_missing_target}', '#{attr_name}', *args)
277 274
                   end
278 275
                 STR
279 276
               end
85  activemodel/test/cases/attribute_methods_test.rb
@@ -5,6 +5,16 @@ class ModelWithAttributes
5 5
 
6 6
   attribute_method_suffix ''
7 7
 
  8
+  class << self
  9
+    define_method(:bar) do
  10
+      'original bar'
  11
+    end
  12
+
  13
+    define_method(:zomg) do
  14
+      'original zomg'
  15
+    end
  16
+  end
  17
+
8 18
   def attributes
9 19
     { :foo => 'value of foo' }
10 20
   end
@@ -21,6 +31,42 @@ class ModelWithAttributes2
21 31
   attribute_method_suffix '_test'
22 32
 end
23 33
 
  34
+class ModelWithAttributesWithSpaces
  35
+  include ActiveModel::AttributeMethods
  36
+
  37
+  attribute_method_suffix ''
  38
+
  39
+  def attributes
  40
+    { :'foo bar' => 'value of foo bar'}
  41
+  end
  42
+
  43
+private
  44
+  def attribute(name)
  45
+    attributes[name.to_sym]
  46
+  end
  47
+end
  48
+
  49
+class ModelWithWeirdNamesAttributes
  50
+  include ActiveModel::AttributeMethods
  51
+
  52
+  attribute_method_suffix ''
  53
+
  54
+  class << self
  55
+    define_method(:'c?d') do
  56
+      'original c?d'
  57
+    end
  58
+  end
  59
+
  60
+  def attributes
  61
+    { :'a?b' => 'value of a?b' }
  62
+  end
  63
+
  64
+private
  65
+  def attribute(name)
  66
+    attributes[name.to_sym]
  67
+  end
  68
+end
  69
+
24 70
 class AttributeMethodsTest < ActiveModel::TestCase
25 71
   test 'unrelated classes should not share attribute method matchers' do
26 72
     assert_not_equal ModelWithAttributes.send(:attribute_method_matchers),
@@ -35,6 +81,45 @@ class AttributeMethodsTest < ActiveModel::TestCase
35 81
     assert_equal "value of foo", ModelWithAttributes.new.foo
36 82
   end
37 83
 
  84
+  test '#define_attribute_methods generates attribute methods with spaces in their names' do
  85
+    ModelWithAttributesWithSpaces.define_attribute_methods([:'foo bar'])
  86
+
  87
+    assert_respond_to ModelWithAttributesWithSpaces.new, :'foo bar'
  88
+    assert_equal "value of foo bar", ModelWithAttributesWithSpaces.new.send(:'foo bar')
  89
+  end
  90
+
  91
+  def test_defined_methods_always_return_duped_string
  92
+    ModelWithAttributes.define_attr_method(:zomg, 'lol')
  93
+    assert_equal 'lol', ModelWithAttributes.zomg
  94
+    ModelWithAttributes.zomg << 'bbq'
  95
+    assert_equal 'lol', ModelWithAttributes.zomg
  96
+  end
  97
+
  98
+  test '#define_attr_method generates attribute method' do
  99
+    ModelWithAttributes.define_attr_method(:bar, 'bar')
  100
+
  101
+    assert_respond_to ModelWithAttributes, :bar
  102
+    assert_equal "original bar", ModelWithAttributes.original_bar
  103
+    assert_equal "bar", ModelWithAttributes.bar
  104
+    ModelWithAttributes.define_attr_method(:bar)
  105
+    assert !ModelWithAttributes.bar
  106
+  end
  107
+
  108
+  test '#define_attr_method generates attribute method with invalid identifier characters' do
  109
+    ModelWithWeirdNamesAttributes.define_attr_method(:'c?d', 'c?d')
  110
+
  111
+    assert_respond_to ModelWithWeirdNamesAttributes, :'c?d'
  112
+    assert_equal "original c?d", ModelWithWeirdNamesAttributes.send('original_c?d')
  113
+    assert_equal "c?d", ModelWithWeirdNamesAttributes.send('c?d')
  114
+  end
  115
+
  116
+  test '#alias_attribute works with attributes with spaces in their names' do
  117
+    ModelWithAttributesWithSpaces.define_attribute_methods([:'foo bar'])
  118
+    ModelWithAttributesWithSpaces.alias_attribute(:'foo_bar', :'foo bar')
  119
+
  120
+    assert_equal "value of foo bar", ModelWithAttributesWithSpaces.new.foo_bar
  121
+  end
  122
+
38 123
   test '#undefine_attribute_methods removes attribute methods' do
39 124
     ModelWithAttributes.define_attribute_methods([:foo])
40 125
     ModelWithAttributes.undefine_attribute_methods

0 notes on commit 691530a

Please sign in to comment.
Something went wrong with that request. Please try again.