sskirby-activerecord 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. data/CHANGELOG.md +6749 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +222 -0
  4. data/examples/associations.png +0 -0
  5. data/examples/performance.rb +177 -0
  6. data/examples/simple.rb +14 -0
  7. data/lib/active_record.rb +147 -0
  8. data/lib/active_record/aggregations.rb +255 -0
  9. data/lib/active_record/associations.rb +1604 -0
  10. data/lib/active_record/associations/alias_tracker.rb +79 -0
  11. data/lib/active_record/associations/association.rb +239 -0
  12. data/lib/active_record/associations/association_scope.rb +119 -0
  13. data/lib/active_record/associations/belongs_to_association.rb +79 -0
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +34 -0
  15. data/lib/active_record/associations/builder/association.rb +55 -0
  16. data/lib/active_record/associations/builder/belongs_to.rb +85 -0
  17. data/lib/active_record/associations/builder/collection_association.rb +75 -0
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -0
  19. data/lib/active_record/associations/builder/has_many.rb +71 -0
  20. data/lib/active_record/associations/builder/has_one.rb +62 -0
  21. data/lib/active_record/associations/builder/singular_association.rb +32 -0
  22. data/lib/active_record/associations/collection_association.rb +574 -0
  23. data/lib/active_record/associations/collection_proxy.rb +132 -0
  24. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +62 -0
  25. data/lib/active_record/associations/has_many_association.rb +108 -0
  26. data/lib/active_record/associations/has_many_through_association.rb +180 -0
  27. data/lib/active_record/associations/has_one_association.rb +73 -0
  28. data/lib/active_record/associations/has_one_through_association.rb +36 -0
  29. data/lib/active_record/associations/join_dependency.rb +214 -0
  30. data/lib/active_record/associations/join_dependency/join_association.rb +154 -0
  31. data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
  32. data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
  33. data/lib/active_record/associations/join_helper.rb +55 -0
  34. data/lib/active_record/associations/preloader.rb +177 -0
  35. data/lib/active_record/associations/preloader/association.rb +127 -0
  36. data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
  37. data/lib/active_record/associations/preloader/collection_association.rb +24 -0
  38. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
  39. data/lib/active_record/associations/preloader/has_many.rb +17 -0
  40. data/lib/active_record/associations/preloader/has_many_through.rb +15 -0
  41. data/lib/active_record/associations/preloader/has_one.rb +23 -0
  42. data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
  43. data/lib/active_record/associations/preloader/singular_association.rb +21 -0
  44. data/lib/active_record/associations/preloader/through_association.rb +67 -0
  45. data/lib/active_record/associations/singular_association.rb +64 -0
  46. data/lib/active_record/associations/through_association.rb +83 -0
  47. data/lib/active_record/attribute_assignment.rb +221 -0
  48. data/lib/active_record/attribute_methods.rb +272 -0
  49. data/lib/active_record/attribute_methods/before_type_cast.rb +31 -0
  50. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +32 -0
  51. data/lib/active_record/attribute_methods/dirty.rb +101 -0
  52. data/lib/active_record/attribute_methods/primary_key.rb +114 -0
  53. data/lib/active_record/attribute_methods/query.rb +39 -0
  54. data/lib/active_record/attribute_methods/read.rb +135 -0
  55. data/lib/active_record/attribute_methods/serialization.rb +93 -0
  56. data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -0
  57. data/lib/active_record/attribute_methods/write.rb +69 -0
  58. data/lib/active_record/autosave_association.rb +422 -0
  59. data/lib/active_record/base.rb +716 -0
  60. data/lib/active_record/callbacks.rb +275 -0
  61. data/lib/active_record/coders/yaml_column.rb +41 -0
  62. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +452 -0
  63. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +188 -0
  64. data/lib/active_record/connection_adapters/abstract/database_limits.rb +58 -0
  65. data/lib/active_record/connection_adapters/abstract/database_statements.rb +388 -0
  66. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -0
  67. data/lib/active_record/connection_adapters/abstract/quoting.rb +115 -0
  68. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +492 -0
  69. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +598 -0
  70. data/lib/active_record/connection_adapters/abstract_adapter.rb +296 -0
  71. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +653 -0
  72. data/lib/active_record/connection_adapters/column.rb +270 -0
  73. data/lib/active_record/connection_adapters/mysql2_adapter.rb +288 -0
  74. data/lib/active_record/connection_adapters/mysql_adapter.rb +426 -0
  75. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1261 -0
  76. data/lib/active_record/connection_adapters/schema_cache.rb +50 -0
  77. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +55 -0
  78. data/lib/active_record/connection_adapters/sqlite_adapter.rb +577 -0
  79. data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
  80. data/lib/active_record/counter_cache.rb +119 -0
  81. data/lib/active_record/dynamic_finder_match.rb +56 -0
  82. data/lib/active_record/dynamic_matchers.rb +79 -0
  83. data/lib/active_record/dynamic_scope_match.rb +23 -0
  84. data/lib/active_record/errors.rb +195 -0
  85. data/lib/active_record/explain.rb +85 -0
  86. data/lib/active_record/explain_subscriber.rb +21 -0
  87. data/lib/active_record/fixtures.rb +906 -0
  88. data/lib/active_record/fixtures/file.rb +65 -0
  89. data/lib/active_record/identity_map.rb +156 -0
  90. data/lib/active_record/inheritance.rb +167 -0
  91. data/lib/active_record/integration.rb +49 -0
  92. data/lib/active_record/locale/en.yml +40 -0
  93. data/lib/active_record/locking/optimistic.rb +183 -0
  94. data/lib/active_record/locking/pessimistic.rb +77 -0
  95. data/lib/active_record/log_subscriber.rb +68 -0
  96. data/lib/active_record/migration.rb +765 -0
  97. data/lib/active_record/migration/command_recorder.rb +105 -0
  98. data/lib/active_record/model_schema.rb +366 -0
  99. data/lib/active_record/nested_attributes.rb +469 -0
  100. data/lib/active_record/observer.rb +121 -0
  101. data/lib/active_record/persistence.rb +372 -0
  102. data/lib/active_record/query_cache.rb +74 -0
  103. data/lib/active_record/querying.rb +58 -0
  104. data/lib/active_record/railtie.rb +119 -0
  105. data/lib/active_record/railties/console_sandbox.rb +6 -0
  106. data/lib/active_record/railties/controller_runtime.rb +49 -0
  107. data/lib/active_record/railties/databases.rake +620 -0
  108. data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
  109. data/lib/active_record/readonly_attributes.rb +26 -0
  110. data/lib/active_record/reflection.rb +534 -0
  111. data/lib/active_record/relation.rb +534 -0
  112. data/lib/active_record/relation/batches.rb +90 -0
  113. data/lib/active_record/relation/calculations.rb +354 -0
  114. data/lib/active_record/relation/delegation.rb +49 -0
  115. data/lib/active_record/relation/finder_methods.rb +398 -0
  116. data/lib/active_record/relation/predicate_builder.rb +58 -0
  117. data/lib/active_record/relation/query_methods.rb +417 -0
  118. data/lib/active_record/relation/spawn_methods.rb +148 -0
  119. data/lib/active_record/result.rb +34 -0
  120. data/lib/active_record/sanitization.rb +194 -0
  121. data/lib/active_record/schema.rb +58 -0
  122. data/lib/active_record/schema_dumper.rb +204 -0
  123. data/lib/active_record/scoping.rb +152 -0
  124. data/lib/active_record/scoping/default.rb +142 -0
  125. data/lib/active_record/scoping/named.rb +202 -0
  126. data/lib/active_record/serialization.rb +18 -0
  127. data/lib/active_record/serializers/xml_serializer.rb +202 -0
  128. data/lib/active_record/session_store.rb +358 -0
  129. data/lib/active_record/store.rb +50 -0
  130. data/lib/active_record/test_case.rb +73 -0
  131. data/lib/active_record/timestamp.rb +113 -0
  132. data/lib/active_record/transactions.rb +360 -0
  133. data/lib/active_record/translation.rb +22 -0
  134. data/lib/active_record/validations.rb +83 -0
  135. data/lib/active_record/validations/associated.rb +43 -0
  136. data/lib/active_record/validations/uniqueness.rb +180 -0
  137. data/lib/active_record/version.rb +10 -0
  138. data/lib/rails/generators/active_record.rb +25 -0
  139. data/lib/rails/generators/active_record/migration.rb +15 -0
  140. data/lib/rails/generators/active_record/migration/migration_generator.rb +25 -0
  141. data/lib/rails/generators/active_record/migration/templates/migration.rb +31 -0
  142. data/lib/rails/generators/active_record/model/model_generator.rb +43 -0
  143. data/lib/rails/generators/active_record/model/templates/migration.rb +15 -0
  144. data/lib/rails/generators/active_record/model/templates/model.rb +7 -0
  145. data/lib/rails/generators/active_record/model/templates/module.rb +7 -0
  146. data/lib/rails/generators/active_record/observer/observer_generator.rb +15 -0
  147. data/lib/rails/generators/active_record/observer/templates/observer.rb +4 -0
  148. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +25 -0
  149. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +12 -0
  150. metadata +242 -0
@@ -0,0 +1,105 @@
1
+ module ActiveRecord
2
+ class Migration
3
+ # <tt>ActiveRecord::Migration::CommandRecorder</tt> records commands done during
4
+ # a migration and knows how to reverse those commands. The CommandRecorder
5
+ # knows how to invert the following commands:
6
+ #
7
+ # * add_column
8
+ # * add_index
9
+ # * add_timestamps
10
+ # * create_table
11
+ # * remove_timestamps
12
+ # * rename_column
13
+ # * rename_index
14
+ # * rename_table
15
+ class CommandRecorder
16
+ attr_accessor :commands, :delegate
17
+
18
+ def initialize(delegate = nil)
19
+ @commands = []
20
+ @delegate = delegate
21
+ end
22
+
23
+ # record +command+. +command+ should be a method name and arguments.
24
+ # For example:
25
+ #
26
+ # recorder.record(:method_name, [:arg1, :arg2])
27
+ def record(*command)
28
+ @commands << command
29
+ end
30
+
31
+ # Returns a list that represents commands that are the inverse of the
32
+ # commands stored in +commands+. For example:
33
+ #
34
+ # recorder.record(:rename_table, [:old, :new])
35
+ # recorder.inverse # => [:rename_table, [:new, :old]]
36
+ #
37
+ # This method will raise an +IrreversibleMigration+ exception if it cannot
38
+ # invert the +commands+.
39
+ def inverse
40
+ @commands.reverse.map { |name, args|
41
+ method = :"invert_#{name}"
42
+ raise IrreversibleMigration unless respond_to?(method, true)
43
+ send(method, args)
44
+ }
45
+ end
46
+
47
+ def respond_to?(*args) # :nodoc:
48
+ super || delegate.respond_to?(*args)
49
+ end
50
+
51
+ [:create_table, :change_table, :rename_table, :add_column, :remove_column, :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps, :change_column, :change_column_default].each do |method|
52
+ class_eval <<-EOV, __FILE__, __LINE__ + 1
53
+ def #{method}(*args) # def create_table(*args)
54
+ record(:"#{method}", args) # record(:create_table, args)
55
+ end # end
56
+ EOV
57
+ end
58
+
59
+ private
60
+
61
+ def invert_create_table(args)
62
+ [:drop_table, [args.first]]
63
+ end
64
+
65
+ def invert_rename_table(args)
66
+ [:rename_table, args.reverse]
67
+ end
68
+
69
+ def invert_add_column(args)
70
+ [:remove_column, args.first(2)]
71
+ end
72
+
73
+ def invert_rename_index(args)
74
+ [:rename_index, [args.first] + args.last(2).reverse]
75
+ end
76
+
77
+ def invert_rename_column(args)
78
+ [:rename_column, [args.first] + args.last(2).reverse]
79
+ end
80
+
81
+ def invert_add_index(args)
82
+ table, columns, options = *args
83
+ index_name = options.try(:[], :name)
84
+ options_hash = index_name ? {:name => index_name} : {:column => columns}
85
+ [:remove_index, [table, options_hash]]
86
+ end
87
+
88
+ def invert_remove_timestamps(args)
89
+ [:add_timestamps, args]
90
+ end
91
+
92
+ def invert_add_timestamps(args)
93
+ [:remove_timestamps, args]
94
+ end
95
+
96
+ # Forwards any missing method call to the \target.
97
+ def method_missing(method, *args, &block)
98
+ @delegate.send(method, *args, &block)
99
+ rescue NoMethodError => e
100
+ raise e, e.message.sub(/ for #<.*$/, " via proxy for #{@delegate}")
101
+ end
102
+
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,366 @@
1
+ require 'active_support/concern'
2
+
3
+ module ActiveRecord
4
+ module ModelSchema
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ ##
9
+ # :singleton-method:
10
+ # Accessor for the prefix type that will be prepended to every primary key column name.
11
+ # The options are :table_name and :table_name_with_underscore. If the first is specified,
12
+ # the Product class will look for "productid" instead of "id" as the primary column. If the
13
+ # latter is specified, the Product class will look for "product_id" instead of "id". Remember
14
+ # that this is a global setting for all Active Records.
15
+ cattr_accessor :primary_key_prefix_type, :instance_writer => false
16
+ self.primary_key_prefix_type = nil
17
+
18
+ ##
19
+ # :singleton-method:
20
+ # Accessor for the name of the prefix string to prepend to every table name. So if set
21
+ # to "basecamp_", all table names will be named like "basecamp_projects", "basecamp_people",
22
+ # etc. This is a convenient way of creating a namespace for tables in a shared database.
23
+ # By default, the prefix is the empty string.
24
+ #
25
+ # If you are organising your models within modules you can add a prefix to the models within
26
+ # a namespace by defining a singleton method in the parent module called table_name_prefix which
27
+ # returns your chosen prefix.
28
+ class_attribute :table_name_prefix, :instance_writer => false
29
+ self.table_name_prefix = ""
30
+
31
+ ##
32
+ # :singleton-method:
33
+ # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
34
+ # "people_basecamp"). By default, the suffix is the empty string.
35
+ class_attribute :table_name_suffix, :instance_writer => false
36
+ self.table_name_suffix = ""
37
+
38
+ ##
39
+ # :singleton-method:
40
+ # Indicates whether table names should be the pluralized versions of the corresponding class names.
41
+ # If true, the default table name for a Product class will be +products+. If false, it would just be +product+.
42
+ # See table_name for the full rules on table/class naming. This is true, by default.
43
+ class_attribute :pluralize_table_names, :instance_writer => false
44
+ self.pluralize_table_names = true
45
+ end
46
+
47
+ module ClassMethods
48
+ # Guesses the table name (in forced lower-case) based on the name of the class in the
49
+ # inheritance hierarchy descending directly from ActiveRecord::Base. So if the hierarchy
50
+ # looks like: Reply < Message < ActiveRecord::Base, then Message is used
51
+ # to guess the table name even when called on Reply. The rules used to do the guess
52
+ # are handled by the Inflector class in Active Support, which knows almost all common
53
+ # English inflections. You can add new inflections in config/initializers/inflections.rb.
54
+ #
55
+ # Nested classes are given table names prefixed by the singular form of
56
+ # the parent's table name. Enclosing modules are not considered.
57
+ #
58
+ # ==== Examples
59
+ #
60
+ # class Invoice < ActiveRecord::Base
61
+ # end
62
+ #
63
+ # file class table_name
64
+ # invoice.rb Invoice invoices
65
+ #
66
+ # class Invoice < ActiveRecord::Base
67
+ # class Lineitem < ActiveRecord::Base
68
+ # end
69
+ # end
70
+ #
71
+ # file class table_name
72
+ # invoice.rb Invoice::Lineitem invoice_lineitems
73
+ #
74
+ # module Invoice
75
+ # class Lineitem < ActiveRecord::Base
76
+ # end
77
+ # end
78
+ #
79
+ # file class table_name
80
+ # invoice/lineitem.rb Invoice::Lineitem lineitems
81
+ #
82
+ # Additionally, the class-level +table_name_prefix+ is prepended and the
83
+ # +table_name_suffix+ is appended. So if you have "myapp_" as a prefix,
84
+ # the table name guess for an Invoice class becomes "myapp_invoices".
85
+ # Invoice::Lineitem becomes "myapp_invoice_lineitems".
86
+ #
87
+ # You can also set your own table name explicitly:
88
+ #
89
+ # class Mouse < ActiveRecord::Base
90
+ # self.table_name = "mice"
91
+ # end
92
+ #
93
+ # Alternatively, you can override the table_name method to define your
94
+ # own computation. (Possibly using <tt>super</tt> to manipulate the default
95
+ # table name.) Example:
96
+ #
97
+ # class Post < ActiveRecord::Base
98
+ # def self.table_name
99
+ # "special_" + super
100
+ # end
101
+ # end
102
+ # Post.table_name # => "special_posts"
103
+ def table_name
104
+ reset_table_name unless defined?(@table_name)
105
+ @table_name
106
+ end
107
+
108
+ def original_table_name #:nodoc:
109
+ deprecated_original_property_getter :table_name
110
+ end
111
+
112
+ # Sets the table name explicitly. Example:
113
+ #
114
+ # class Project < ActiveRecord::Base
115
+ # self.table_name = "project"
116
+ # end
117
+ #
118
+ # You can also just define your own <tt>self.table_name</tt> method; see
119
+ # the documentation for ActiveRecord::Base#table_name.
120
+ def table_name=(value)
121
+ @original_table_name = @table_name if defined?(@table_name)
122
+ @table_name = value && value.to_s
123
+ @quoted_table_name = nil
124
+ @arel_table = nil
125
+ @relation = Relation.new(self, arel_table)
126
+ end
127
+
128
+ def set_table_name(value = nil, &block) #:nodoc:
129
+ deprecated_property_setter :table_name, value, block
130
+ @quoted_table_name = nil
131
+ @arel_table = nil
132
+ @relation = Relation.new(self, arel_table)
133
+ end
134
+
135
+ # Returns a quoted version of the table name, used to construct SQL statements.
136
+ def quoted_table_name
137
+ @quoted_table_name ||= connection.quote_table_name(table_name)
138
+ end
139
+
140
+ # Computes the table name, (re)sets it internally, and returns it.
141
+ def reset_table_name #:nodoc:
142
+ if abstract_class?
143
+ self.table_name = if superclass == Base || superclass.abstract_class?
144
+ nil
145
+ else
146
+ superclass.table_name
147
+ end
148
+ elsif superclass.abstract_class?
149
+ self.table_name = superclass.table_name || compute_table_name
150
+ else
151
+ self.table_name = compute_table_name
152
+ end
153
+ end
154
+
155
+ def full_table_name_prefix #:nodoc:
156
+ (parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
157
+ end
158
+
159
+ # The name of the column containing the object's class when Single Table Inheritance is used
160
+ def inheritance_column
161
+ if self == Base
162
+ 'type'
163
+ else
164
+ (@inheritance_column ||= nil) || superclass.inheritance_column
165
+ end
166
+ end
167
+
168
+ def original_inheritance_column #:nodoc:
169
+ deprecated_original_property_getter :inheritance_column
170
+ end
171
+
172
+ # Sets the value of inheritance_column
173
+ def inheritance_column=(value)
174
+ @original_inheritance_column = inheritance_column
175
+ @inheritance_column = value.to_s
176
+ end
177
+
178
+ def set_inheritance_column(value = nil, &block) #:nodoc:
179
+ deprecated_property_setter :inheritance_column, value, block
180
+ end
181
+
182
+ def sequence_name
183
+ if base_class == self
184
+ @sequence_name ||= reset_sequence_name
185
+ else
186
+ (@sequence_name ||= nil) || base_class.sequence_name
187
+ end
188
+ end
189
+
190
+ def original_sequence_name #:nodoc:
191
+ deprecated_original_property_getter :sequence_name
192
+ end
193
+
194
+ def reset_sequence_name #:nodoc:
195
+ self.sequence_name = connection.default_sequence_name(table_name, primary_key)
196
+ end
197
+
198
+ # Sets the name of the sequence to use when generating ids to the given
199
+ # value, or (if the value is nil or false) to the value returned by the
200
+ # given block. This is required for Oracle and is useful for any
201
+ # database which relies on sequences for primary key generation.
202
+ #
203
+ # If a sequence name is not explicitly set when using Oracle or Firebird,
204
+ # it will default to the commonly used pattern of: #{table_name}_seq
205
+ #
206
+ # If a sequence name is not explicitly set when using PostgreSQL, it
207
+ # will discover the sequence corresponding to your primary key for you.
208
+ #
209
+ # class Project < ActiveRecord::Base
210
+ # self.sequence_name = "projectseq" # default would have been "project_seq"
211
+ # end
212
+ def sequence_name=(value)
213
+ @original_sequence_name = @sequence_name if defined?(@sequence_name)
214
+ @sequence_name = value.to_s
215
+ end
216
+
217
+ def set_sequence_name(value = nil, &block) #:nodoc:
218
+ deprecated_property_setter :sequence_name, value, block
219
+ end
220
+
221
+ # Indicates whether the table associated with this class exists
222
+ def table_exists?
223
+ connection.schema_cache.table_exists?(table_name)
224
+ end
225
+
226
+ # Returns an array of column objects for the table associated with this class.
227
+ def columns
228
+ @columns ||= connection.schema_cache.columns[table_name].map do |col|
229
+ col = col.dup
230
+ col.primary = (col.name == primary_key)
231
+ col
232
+ end
233
+ end
234
+
235
+ # Returns a hash of column objects for the table associated with this class.
236
+ def columns_hash
237
+ @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
238
+ end
239
+
240
+ # Returns a hash where the keys are column names and the values are
241
+ # default values when instantiating the AR object for this table.
242
+ def column_defaults
243
+ @column_defaults ||= Hash[columns.map { |c| [c.name, c.default] }]
244
+ end
245
+
246
+ # Returns an array of column names as strings.
247
+ def column_names
248
+ @column_names ||= columns.map { |column| column.name }
249
+ end
250
+
251
+ # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
252
+ # and columns used for single table inheritance have been removed.
253
+ def content_columns
254
+ @content_columns ||= columns.reject { |c| c.primary || c.name =~ /(_id|_count)$/ || c.name == inheritance_column }
255
+ end
256
+
257
+ # Returns a hash of all the methods added to query each of the columns in the table with the name of the method as the key
258
+ # and true as the value. This makes it possible to do O(1) lookups in respond_to? to check if a given method for attribute
259
+ # is available.
260
+ def column_methods_hash #:nodoc:
261
+ @dynamic_methods_hash ||= column_names.inject(Hash.new(false)) do |methods, attr|
262
+ attr_name = attr.to_s
263
+ methods[attr.to_sym] = attr_name
264
+ methods["#{attr}=".to_sym] = attr_name
265
+ methods["#{attr}?".to_sym] = attr_name
266
+ methods["#{attr}_before_type_cast".to_sym] = attr_name
267
+ methods
268
+ end
269
+ end
270
+
271
+ # Resets all the cached information about columns, which will cause them
272
+ # to be reloaded on the next request.
273
+ #
274
+ # The most common usage pattern for this method is probably in a migration,
275
+ # when just after creating a table you want to populate it with some default
276
+ # values, eg:
277
+ #
278
+ # class CreateJobLevels < ActiveRecord::Migration
279
+ # def up
280
+ # create_table :job_levels do |t|
281
+ # t.integer :id
282
+ # t.string :name
283
+ #
284
+ # t.timestamps
285
+ # end
286
+ #
287
+ # JobLevel.reset_column_information
288
+ # %w{assistant executive manager director}.each do |type|
289
+ # JobLevel.create(:name => type)
290
+ # end
291
+ # end
292
+ #
293
+ # def down
294
+ # drop_table :job_levels
295
+ # end
296
+ # end
297
+ def reset_column_information
298
+ connection.clear_cache!
299
+ undefine_attribute_methods
300
+ connection.schema_cache.clear_table_cache!(table_name) if table_exists?
301
+
302
+ @column_names = @content_columns = @column_defaults = @columns = @columns_hash = nil
303
+ @dynamic_methods_hash = @inheritance_column = nil
304
+ @arel_engine = @relation = nil
305
+ end
306
+
307
+ def clear_cache! # :nodoc:
308
+ connection.schema_cache.clear!
309
+ end
310
+
311
+ private
312
+
313
+ # Guesses the table name, but does not decorate it with prefix and suffix information.
314
+ def undecorated_table_name(class_name = base_class.name)
315
+ table_name = class_name.to_s.demodulize.underscore
316
+ table_name = table_name.pluralize if pluralize_table_names
317
+ table_name
318
+ end
319
+
320
+ # Computes and returns a table name according to default conventions.
321
+ def compute_table_name
322
+ base = base_class
323
+ if self == base
324
+ # Nested classes are prefixed with singular parent table name.
325
+ if parent < ActiveRecord::Base && !parent.abstract_class?
326
+ contained = parent.table_name
327
+ contained = contained.singularize if parent.pluralize_table_names
328
+ contained += '_'
329
+ end
330
+ "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{table_name_suffix}"
331
+ else
332
+ # STI subclasses always use their superclass' table.
333
+ base.table_name
334
+ end
335
+ end
336
+
337
+ def deprecated_property_setter(property, value, block)
338
+ if block
339
+ ActiveSupport::Deprecation.warn(
340
+ "Calling set_#{property} is deprecated. If you need to lazily evaluate " \
341
+ "the #{property}, define your own `self.#{property}` class method. You can use `super` " \
342
+ "to get the default #{property} where you would have called `original_#{property}`."
343
+ )
344
+
345
+ define_attr_method property, value, false, &block
346
+ else
347
+ ActiveSupport::Deprecation.warn(
348
+ "Calling set_#{property} is deprecated. Please use `self.#{property} = 'the_name'` instead."
349
+ )
350
+
351
+ define_attr_method property, value, false
352
+ end
353
+ end
354
+
355
+ def deprecated_original_property_getter(property)
356
+ ActiveSupport::Deprecation.warn("original_#{property} is deprecated. Define self.#{property} and call super instead.")
357
+
358
+ if !instance_variable_defined?("@original_#{property}") && respond_to?("reset_#{property}")
359
+ send("reset_#{property}")
360
+ else
361
+ instance_variable_get("@original_#{property}")
362
+ end
363
+ end
364
+ end
365
+ end
366
+ end