activerecord 3.2.22.4 → 4.0.13

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2799 -617
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +23 -32
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +40 -34
  7. data/lib/active_record/association_relation.rb +22 -0
  8. data/lib/active_record/associations/alias_tracker.rb +4 -2
  9. data/lib/active_record/associations/association.rb +60 -46
  10. data/lib/active_record/associations/association_scope.rb +46 -40
  11. data/lib/active_record/associations/belongs_to_association.rb +17 -4
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  13. data/lib/active_record/associations/builder/association.rb +81 -28
  14. data/lib/active_record/associations/builder/belongs_to.rb +73 -56
  15. data/lib/active_record/associations/builder/collection_association.rb +54 -40
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +23 -41
  17. data/lib/active_record/associations/builder/has_many.rb +8 -64
  18. data/lib/active_record/associations/builder/has_one.rb +13 -50
  19. data/lib/active_record/associations/builder/singular_association.rb +13 -13
  20. data/lib/active_record/associations/collection_association.rb +130 -96
  21. data/lib/active_record/associations/collection_proxy.rb +916 -63
  22. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +15 -13
  23. data/lib/active_record/associations/has_many_association.rb +35 -8
  24. data/lib/active_record/associations/has_many_through_association.rb +37 -17
  25. data/lib/active_record/associations/has_one_association.rb +42 -19
  26. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  27. data/lib/active_record/associations/join_dependency/join_association.rb +39 -22
  28. data/lib/active_record/associations/join_dependency/join_base.rb +2 -2
  29. data/lib/active_record/associations/join_dependency/join_part.rb +21 -8
  30. data/lib/active_record/associations/join_dependency.rb +30 -9
  31. data/lib/active_record/associations/join_helper.rb +1 -11
  32. data/lib/active_record/associations/preloader/association.rb +29 -33
  33. data/lib/active_record/associations/preloader/collection_association.rb +1 -1
  34. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +2 -2
  35. data/lib/active_record/associations/preloader/has_many_through.rb +6 -2
  36. data/lib/active_record/associations/preloader/has_one.rb +1 -1
  37. data/lib/active_record/associations/preloader/through_association.rb +13 -17
  38. data/lib/active_record/associations/preloader.rb +20 -43
  39. data/lib/active_record/associations/singular_association.rb +11 -11
  40. data/lib/active_record/associations/through_association.rb +3 -3
  41. data/lib/active_record/associations.rb +223 -282
  42. data/lib/active_record/attribute_assignment.rb +134 -154
  43. data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
  44. data/lib/active_record/attribute_methods/dirty.rb +36 -29
  45. data/lib/active_record/attribute_methods/primary_key.rb +45 -31
  46. data/lib/active_record/attribute_methods/query.rb +5 -4
  47. data/lib/active_record/attribute_methods/read.rb +67 -90
  48. data/lib/active_record/attribute_methods/serialization.rb +133 -70
  49. data/lib/active_record/attribute_methods/time_zone_conversion.rb +51 -45
  50. data/lib/active_record/attribute_methods/write.rb +34 -39
  51. data/lib/active_record/attribute_methods.rb +268 -108
  52. data/lib/active_record/autosave_association.rb +80 -73
  53. data/lib/active_record/base.rb +54 -451
  54. data/lib/active_record/callbacks.rb +60 -22
  55. data/lib/active_record/coders/yaml_column.rb +18 -21
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +347 -197
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +146 -138
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +25 -19
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +19 -3
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +151 -142
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +499 -217
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +208 -0
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +209 -44
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +169 -61
  67. data/lib/active_record/connection_adapters/column.rb +67 -36
  68. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +28 -29
  70. data/lib/active_record/connection_adapters/mysql_adapter.rb +200 -73
  71. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +98 -0
  72. data/lib/active_record/connection_adapters/postgresql/cast.rb +160 -0
  73. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +240 -0
  74. data/lib/active_record/connection_adapters/postgresql/oid.rb +374 -0
  75. data/lib/active_record/connection_adapters/postgresql/quoting.rb +183 -0
  76. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  77. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +508 -0
  78. data/lib/active_record/connection_adapters/postgresql_adapter.rb +544 -899
  79. data/lib/active_record/connection_adapters/schema_cache.rb +76 -16
  80. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +595 -16
  81. data/lib/active_record/connection_handling.rb +98 -0
  82. data/lib/active_record/core.rb +472 -0
  83. data/lib/active_record/counter_cache.rb +107 -108
  84. data/lib/active_record/dynamic_matchers.rb +115 -63
  85. data/lib/active_record/errors.rb +36 -18
  86. data/lib/active_record/explain.rb +15 -63
  87. data/lib/active_record/explain_registry.rb +30 -0
  88. data/lib/active_record/explain_subscriber.rb +8 -4
  89. data/lib/active_record/fixture_set/file.rb +55 -0
  90. data/lib/active_record/fixtures.rb +159 -155
  91. data/lib/active_record/inheritance.rb +93 -59
  92. data/lib/active_record/integration.rb +8 -8
  93. data/lib/active_record/locale/en.yml +8 -1
  94. data/lib/active_record/locking/optimistic.rb +39 -43
  95. data/lib/active_record/locking/pessimistic.rb +4 -4
  96. data/lib/active_record/log_subscriber.rb +19 -9
  97. data/lib/active_record/migration/command_recorder.rb +102 -33
  98. data/lib/active_record/migration/join_table.rb +15 -0
  99. data/lib/active_record/migration.rb +411 -173
  100. data/lib/active_record/model_schema.rb +81 -94
  101. data/lib/active_record/nested_attributes.rb +173 -131
  102. data/lib/active_record/null_relation.rb +67 -0
  103. data/lib/active_record/persistence.rb +254 -106
  104. data/lib/active_record/query_cache.rb +18 -36
  105. data/lib/active_record/querying.rb +19 -15
  106. data/lib/active_record/railtie.rb +113 -38
  107. data/lib/active_record/railties/console_sandbox.rb +3 -4
  108. data/lib/active_record/railties/controller_runtime.rb +4 -3
  109. data/lib/active_record/railties/databases.rake +115 -368
  110. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  111. data/lib/active_record/readonly_attributes.rb +7 -3
  112. data/lib/active_record/reflection.rb +110 -61
  113. data/lib/active_record/relation/batches.rb +29 -29
  114. data/lib/active_record/relation/calculations.rb +155 -125
  115. data/lib/active_record/relation/delegation.rb +94 -18
  116. data/lib/active_record/relation/finder_methods.rb +151 -203
  117. data/lib/active_record/relation/merger.rb +188 -0
  118. data/lib/active_record/relation/predicate_builder.rb +85 -42
  119. data/lib/active_record/relation/query_methods.rb +793 -146
  120. data/lib/active_record/relation/spawn_methods.rb +43 -150
  121. data/lib/active_record/relation.rb +293 -173
  122. data/lib/active_record/result.rb +48 -7
  123. data/lib/active_record/runtime_registry.rb +17 -0
  124. data/lib/active_record/sanitization.rb +41 -54
  125. data/lib/active_record/schema.rb +19 -12
  126. data/lib/active_record/schema_dumper.rb +41 -41
  127. data/lib/active_record/schema_migration.rb +46 -0
  128. data/lib/active_record/scoping/default.rb +56 -52
  129. data/lib/active_record/scoping/named.rb +78 -103
  130. data/lib/active_record/scoping.rb +54 -124
  131. data/lib/active_record/serialization.rb +6 -2
  132. data/lib/active_record/serializers/xml_serializer.rb +9 -15
  133. data/lib/active_record/statement_cache.rb +26 -0
  134. data/lib/active_record/store.rb +131 -15
  135. data/lib/active_record/tasks/database_tasks.rb +204 -0
  136. data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
  137. data/lib/active_record/tasks/mysql_database_tasks.rb +144 -0
  138. data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
  139. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  140. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  141. data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
  142. data/lib/active_record/test_case.rb +67 -38
  143. data/lib/active_record/timestamp.rb +16 -11
  144. data/lib/active_record/transactions.rb +73 -51
  145. data/lib/active_record/validations/associated.rb +19 -13
  146. data/lib/active_record/validations/presence.rb +65 -0
  147. data/lib/active_record/validations/uniqueness.rb +110 -57
  148. data/lib/active_record/validations.rb +18 -17
  149. data/lib/active_record/version.rb +7 -6
  150. data/lib/active_record.rb +63 -45
  151. data/lib/rails/generators/active_record/migration/migration_generator.rb +45 -8
  152. data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +4 -0
  153. data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
  154. data/lib/rails/generators/active_record/model/model_generator.rb +5 -4
  155. data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
  156. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  157. data/lib/rails/generators/active_record.rb +3 -5
  158. metadata +43 -29
  159. data/examples/associations.png +0 -0
  160. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  161. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  162. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  163. data/lib/active_record/dynamic_finder_match.rb +0 -68
  164. data/lib/active_record/dynamic_scope_match.rb +0 -23
  165. data/lib/active_record/fixtures/file.rb +0 -65
  166. data/lib/active_record/identity_map.rb +0 -162
  167. data/lib/active_record/observer.rb +0 -121
  168. data/lib/active_record/session_store.rb +0 -360
  169. data/lib/rails/generators/active_record/migration.rb +0 -15
  170. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  171. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  172. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  173. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,64 +1,70 @@
1
- require 'active_support/core_ext/class/attribute'
2
- require 'active_support/core_ext/object/inclusion'
3
-
4
1
  module ActiveRecord
5
2
  module AttributeMethods
6
3
  module TimeZoneConversion
4
+ class Type # :nodoc:
5
+ def initialize(column)
6
+ @column = column
7
+ end
8
+
9
+ def type_cast(value)
10
+ value = @column.type_cast(value)
11
+ value.acts_like?(:time) ? value.in_time_zone : value
12
+ end
13
+
14
+ def type
15
+ @column.type
16
+ end
17
+ end
18
+
7
19
  extend ActiveSupport::Concern
8
20
 
9
21
  included do
10
- cattr_accessor :time_zone_aware_attributes, :instance_writer => false
22
+ mattr_accessor :time_zone_aware_attributes, instance_writer: false
11
23
  self.time_zone_aware_attributes = false
12
24
 
13
- class_attribute :skip_time_zone_conversion_for_attributes, :instance_writer => false
25
+ class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false
14
26
  self.skip_time_zone_conversion_for_attributes = []
15
27
  end
16
28
 
17
29
  module ClassMethods
18
30
  protected
19
- # The enhanced read method automatically converts the UTC time stored in the database to the time
20
- # zone stored in Time.zone.
21
- def attribute_cast_code(attr_name)
22
- column = columns_hash[attr_name]
23
-
24
- if create_time_zone_conversion_attribute?(attr_name, column)
25
- typecast = "v = #{super}"
26
- time_zone_conversion = "v.acts_like?(:time) ? v.in_time_zone : v"
27
-
28
- "((#{typecast}) && (#{time_zone_conversion}))"
29
- else
30
- super
31
- end
32
- end
33
-
34
- # Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled.
35
- # This enhanced write method will automatically convert the time passed to it to the zone stored in Time.zone.
36
- def define_method_attribute=(attr_name)
37
- if create_time_zone_conversion_attribute?(attr_name, columns_hash[attr_name])
38
- method_body, line = <<-EOV, __LINE__ + 1
39
- def #{attr_name}=(original_time)
40
- original_time = nil if original_time.blank?
41
- time = original_time
42
- unless time.acts_like?(:time)
43
- time = time.is_a?(String) ? Time.zone.parse(time) : time.to_time rescue time
44
- end
45
- time = time.in_time_zone rescue nil if time
46
- previous_time = attribute_changed?("#{attr_name}") ? changed_attributes["#{attr_name}"] : read_attribute(:#{attr_name})
47
- write_attribute(:#{attr_name}, original_time)
48
- #{attr_name}_will_change! if previous_time != time
49
- @attributes_cache["#{attr_name}"] = time
50
- end
51
- EOV
52
- generated_attribute_methods.module_eval(method_body, __FILE__, line)
53
- else
54
- super
55
- end
31
+ # Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled.
32
+ # This enhanced write method will automatically convert the time passed to it to the zone stored in Time.zone.
33
+ def define_method_attribute=(attr_name)
34
+ if create_time_zone_conversion_attribute?(attr_name, columns_hash[attr_name])
35
+ method_body, line = <<-EOV, __LINE__ + 1
36
+ def #{attr_name}=(time)
37
+ time_with_zone = convert_value_to_time_zone(time)
38
+ previous_time = attribute_changed?("#{attr_name}") ? changed_attributes["#{attr_name}"] : read_attribute(:#{attr_name})
39
+ write_attribute(:#{attr_name}, time)
40
+ #{attr_name}_will_change! if previous_time != time_with_zone
41
+ @attributes_cache["#{attr_name}"] = time_with_zone
42
+ end
43
+ EOV
44
+ generated_attribute_methods.module_eval(method_body, __FILE__, line)
45
+ else
46
+ super
56
47
  end
48
+ end
57
49
 
58
50
  private
59
- def create_time_zone_conversion_attribute?(name, column)
60
- time_zone_aware_attributes && !self.skip_time_zone_conversion_for_attributes.include?(name.to_sym) && column.type.in?([:datetime, :timestamp])
61
- end
51
+ def create_time_zone_conversion_attribute?(name, column)
52
+ time_zone_aware_attributes &&
53
+ !self.skip_time_zone_conversion_for_attributes.include?(name.to_sym) &&
54
+ (:datetime == column.type || :timestamp == column.type)
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def convert_value_to_time_zone(value)
61
+ if value.is_a?(Array)
62
+ value.map { |v| convert_value_to_time_zone(v) }
63
+ elsif value.respond_to?(:in_time_zone)
64
+ value.in_time_zone
65
+ else
66
+ nil
67
+ end
62
68
  end
63
69
  end
64
70
  end
@@ -9,62 +9,57 @@ module ActiveRecord
9
9
 
10
10
  module ClassMethods
11
11
  protected
12
- def define_method_attribute=(attr_name)
13
- if attr_name =~ ActiveModel::AttributeMethods::NAME_COMPILABLE_REGEXP
14
- generated_attribute_methods.module_eval("def #{attr_name}=(new_value); write_attribute('#{attr_name}', new_value); end", __FILE__, __LINE__)
15
- else
16
- generated_attribute_methods.send(:define_method, "#{attr_name}=") do |new_value|
17
- write_attribute(attr_name, new_value)
18
- end
12
+
13
+ # See define_method_attribute in read.rb for an explanation of
14
+ # this code.
15
+ def define_method_attribute=(name)
16
+ safe_name = name.unpack('h*').first
17
+ generated_attribute_methods::AttrNames.set_name_cache safe_name, name
18
+
19
+ generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
20
+ def __temp__#{safe_name}=(value)
21
+ write_attribute(AttrNames::ATTR_#{safe_name}, value)
19
22
  end
20
- end
23
+ alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
24
+ undef_method :__temp__#{safe_name}=
25
+ STR
26
+ end
21
27
  end
22
28
 
23
- # Updates the attribute identified by <tt>attr_name</tt> with the specified +value+. Empty strings
24
- # for fixnum and float columns are turned into +nil+.
29
+ # Updates the attribute identified by <tt>attr_name</tt> with the
30
+ # specified +value+. Empty strings for fixnum and float columns are
31
+ # turned into +nil+.
25
32
  def write_attribute(attr_name, value)
26
33
  attr_name = attr_name.to_s
27
34
  attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key
28
35
  @attributes_cache.delete(attr_name)
29
36
  column = column_for_attribute(attr_name)
30
37
 
31
- unless column || @attributes.has_key?(attr_name)
32
- ActiveSupport::Deprecation.warn(
33
- "You're trying to create an attribute `#{attr_name}'. Writing arbitrary " \
34
- "attributes on a model is deprecated. Please just use `attr_writer` etc."
35
- )
38
+ # If we're dealing with a binary column, write the data to the cache
39
+ # so we don't attempt to typecast multiple times.
40
+ if column && column.binary?
41
+ @attributes_cache[attr_name] = value
36
42
  end
37
43
 
38
- @attributes[attr_name] = type_cast_attribute_for_write(column, value)
44
+ if column || @attributes.has_key?(attr_name)
45
+ @attributes[attr_name] = type_cast_attribute_for_write(column, value)
46
+ else
47
+ raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{attr_name}'"
48
+ end
39
49
  end
40
50
  alias_method :raw_write_attribute, :write_attribute
41
51
 
42
52
  private
43
- # Handle *= for method_missing.
44
- def attribute=(attribute_name, value)
45
- write_attribute(attribute_name, value)
46
- end
53
+ # Handle *= for method_missing.
54
+ def attribute=(attribute_name, value)
55
+ write_attribute(attribute_name, value)
56
+ end
47
57
 
48
- def type_cast_attribute_for_write(column, value)
49
- if column && column.number?
50
- convert_number_column_value(value)
51
- else
52
- value
53
- end
54
- end
58
+ def type_cast_attribute_for_write(column, value)
59
+ return value unless column
55
60
 
56
- def convert_number_column_value(value)
57
- case value
58
- when FalseClass
59
- 0
60
- when TrueClass
61
- 1
62
- when String
63
- value.presence
64
- else
65
- value
66
- end
67
- end
61
+ column.type_cast_for_write value
62
+ end
68
63
  end
69
64
  end
70
65
  end