Skip to content
This repository
Browse code

much code can be deleted thanks to @tenderlove's refactoring

  • Loading branch information...
commit 6cff09038d5d78e6a4a12d0a27c6b1b87f0a5147 1 parent 9897b9a
Jon Leighton jonleighton authored
8 activerecord/lib/active_record/attribute_methods.rb
@@ -49,14 +49,6 @@ def attribute_methods_generated?
49 49 @attribute_methods_generated ||= false
50 50 end
51 51
52   - # We will define the methods as instance methods, but will call them as singleton
53   - # methods. This allows us to use method_defined? to check if the method exists,
54   - # which is fast and won't give any false positives from the ancestors (because
55   - # there are no ancestors).
56   - def generated_external_attribute_methods
57   - @generated_external_attribute_methods ||= Module.new { extend self }
58   - end
59   -
60 52 def undefine_attribute_methods
61 53 super if attribute_methods_generated?
62 54 @attribute_methods_generated = false
6 activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -43,12 +43,6 @@ def define_method_attribute(attr_name)
43 43
44 44 if attr_name == primary_key && attr_name != 'id'
45 45 generated_attribute_methods.send(:alias_method, :id, primary_key)
46   - generated_external_attribute_methods.module_eval <<-CODE, __FILE__, __LINE__
47   - def id(v, attributes, attributes_cache, attr_name)
48   - attr_name = '#{primary_key}'
49   - send(attr_name, attributes[attr_name], attributes, attributes_cache, attr_name)
50   - end
51   - CODE
52 46 end
53 47 end
54 48
64 activerecord/lib/active_record/attribute_methods/read.rb
@@ -29,35 +29,8 @@ def cache_attribute?(attr_name)
29 29 cached_attributes.include?(attr_name)
30 30 end
31 31
32   - def undefine_attribute_methods
33   - generated_external_attribute_methods.module_eval do
34   - instance_methods.each { |m| undef_method(m) }
35   - end
36   -
37   - super
38   - end
39   -
40   - def type_cast_attribute(attr_name, attributes, cache = {}) #:nodoc:
41   - return unless attr_name
42   - attr_name = attr_name.to_s
43   -
44   - if generated_external_attribute_methods.method_defined?(attr_name)
45   - if attributes.has_key?(attr_name) || attr_name == 'id'
46   - generated_external_attribute_methods.send(attr_name, attributes[attr_name], attributes, cache, attr_name)
47   - end
48   - elsif !attribute_methods_generated?
49   - # If we haven't generated the caster methods yet, do that and
50   - # then try again
51   - define_attribute_methods
52   - type_cast_attribute(attr_name, attributes, cache)
53   - else
54   - # If we get here, the attribute has no associated DB column, so
55   - # just return it verbatim.
56   - attributes[attr_name]
57   - end
58   - end
59   -
60 32 protected
  33 +
61 34 # We want to generate the methods via module_eval rather than define_method,
62 35 # because define_method is slower on dispatch and uses more memory (because it
63 36 # creates a closure).
@@ -67,19 +40,9 @@ def type_cast_attribute(attr_name, attributes, cache = {}) #:nodoc:
67 40 # we first define with the __temp__ identifier, and then use alias method to
68 41 # rename it to what we want.
69 42 def define_method_attribute(attr_name)
70   - cast_code = attribute_cast_code(attr_name)
71   -
72 43 generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
73 44 def __temp__
74   - #{internal_attribute_access_code(attr_name, cast_code)}
75   - end
76   - alias_method '#{attr_name}', :__temp__
77   - undef_method :__temp__
78   - STR
79   -
80   - generated_external_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
81   - def __temp__(v, attributes, attributes_cache, attr_name)
82   - #{external_attribute_access_code(attr_name, cast_code)}
  45 + read_attribute('#{attr_name}') { |n| missing_attribute(n, caller) }
83 46 end
84 47 alias_method '#{attr_name}', :__temp__
85 48 undef_method :__temp__
@@ -87,6 +50,7 @@ def __temp__(v, attributes, attributes_cache, attr_name)
87 50 end
88 51
89 52 private
  53 +
90 54 def cacheable_column?(column)
91 55 if attribute_types_cached_by_default == ATTRIBUTE_TYPES_CACHED_BY_DEFAULT
92 56 ! serialized_attributes.include? column.name
@@ -94,24 +58,6 @@ def cacheable_column?(column)
94 58 attribute_types_cached_by_default.include?(column.type)
95 59 end
96 60 end
97   -
98   - def internal_attribute_access_code(attr_name, cast_code)
99   - "read_attribute('#{attr_name}') { |n| missing_attribute(n, caller) }"
100   - end
101   -
102   - def external_attribute_access_code(attr_name, cast_code)
103   - access_code = "v && #{cast_code}"
104   -
105   - if cache_attribute?(attr_name)
106   - access_code = "attributes_cache[attr_name] ||= (#{access_code})"
107   - end
108   -
109   - access_code
110   - end
111   -
112   - def attribute_cast_code(attr_name)
113   - columns_hash[attr_name].type_cast_code('v')
114   - end
115 61 end
116 62
117 63 # Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
@@ -120,7 +66,9 @@ def read_attribute(attr_name)
120 66 # If it's cached, just return it
121 67 @attributes_cache.fetch(attr_name.to_s) { |name|
122 68 column = @columns_hash.fetch(name) {
123   - return self.class.type_cast_attribute(name, @attributes, @attributes_cache)
  69 + return @attributes.fetch(name) {
  70 + @attributes[self.class.primary_key] if name == 'id'
  71 + }
124 72 }
125 73
126 74 value = @attributes.fetch(name) {

7 comments on commit 6cff090

Jeremy Kemper
Owner

:heart::heart::heart::heart::heart::heart:

Aaron Patterson

So these are the magic lines I couldn't figure out! :heart:

Aaron Patterson

I wonder if we can deprecate or remove type_cast_code

Aaron Patterson
Owner

Yay!

Diego Plentz

in the middle of all this bikeshedding, you guys still rock :heart:

Jon Leighton

I think so. Will you investigate or shall I?

Matthew McFarling

Deleting code is so awesome <3!

Nick Bugaiov

<3<3<3!

Aaron Patterson

Or add a ticket and I can investigate later. :-)

Lucas Prim

Aint no way not to love it! <3 <3 <3!

Ernie Miller

So much love in this thread. I just want to bask in the positivity. :heart:

Carlos Antonio da Silva

Hey guys, just a follow up, I've added a deprecation warning to type_cast_code, as it's not being used anywhere else in the code base =)

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