activerecord 3.2.22.5 → 4.0.0.beta1

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 (162) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1024 -543
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +20 -29
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record.rb +55 -44
  7. data/lib/active_record/aggregations.rb +40 -34
  8. data/lib/active_record/associations.rb +204 -276
  9. data/lib/active_record/associations/alias_tracker.rb +1 -1
  10. data/lib/active_record/associations/association.rb +30 -35
  11. data/lib/active_record/associations/association_scope.rb +40 -40
  12. data/lib/active_record/associations/belongs_to_association.rb +15 -2
  13. data/lib/active_record/associations/builder/association.rb +81 -28
  14. data/lib/active_record/associations/builder/belongs_to.rb +35 -57
  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 +92 -88
  21. data/lib/active_record/associations/collection_proxy.rb +913 -63
  22. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +12 -10
  23. data/lib/active_record/associations/has_many_association.rb +35 -9
  24. data/lib/active_record/associations/has_many_through_association.rb +24 -14
  25. data/lib/active_record/associations/has_one_association.rb +33 -13
  26. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  27. data/lib/active_record/associations/join_dependency.rb +2 -2
  28. data/lib/active_record/associations/join_dependency/join_association.rb +17 -22
  29. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  30. data/lib/active_record/associations/join_helper.rb +1 -11
  31. data/lib/active_record/associations/preloader.rb +14 -17
  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 +1 -1
  35. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  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/singular_association.rb +11 -11
  39. data/lib/active_record/associations/through_association.rb +2 -2
  40. data/lib/active_record/attribute_assignment.rb +133 -153
  41. data/lib/active_record/attribute_methods.rb +196 -93
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
  43. data/lib/active_record/attribute_methods/dirty.rb +31 -28
  44. data/lib/active_record/attribute_methods/primary_key.rb +38 -30
  45. data/lib/active_record/attribute_methods/query.rb +5 -4
  46. data/lib/active_record/attribute_methods/read.rb +62 -91
  47. data/lib/active_record/attribute_methods/serialization.rb +97 -66
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -45
  49. data/lib/active_record/attribute_methods/write.rb +32 -39
  50. data/lib/active_record/autosave_association.rb +56 -70
  51. data/lib/active_record/base.rb +53 -450
  52. data/lib/active_record/callbacks.rb +53 -18
  53. data/lib/active_record/coders/yaml_column.rb +11 -9
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +353 -197
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +130 -131
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -19
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +23 -3
  59. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +101 -91
  60. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +59 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +225 -96
  62. data/lib/active_record/connection_adapters/abstract/transaction.rb +203 -0
  63. data/lib/active_record/connection_adapters/abstract_adapter.rb +99 -46
  64. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +114 -36
  65. data/lib/active_record/connection_adapters/column.rb +46 -24
  66. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  67. data/lib/active_record/connection_adapters/mysql2_adapter.rb +16 -32
  68. data/lib/active_record/connection_adapters/mysql_adapter.rb +181 -64
  69. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +97 -0
  70. data/lib/active_record/connection_adapters/postgresql/cast.rb +132 -0
  71. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +242 -0
  72. data/lib/active_record/connection_adapters/postgresql/oid.rb +347 -0
  73. data/lib/active_record/connection_adapters/postgresql/quoting.rb +158 -0
  74. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  75. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +448 -0
  76. data/lib/active_record/connection_adapters/postgresql_adapter.rb +454 -885
  77. data/lib/active_record/connection_adapters/schema_cache.rb +48 -16
  78. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +574 -13
  79. data/lib/active_record/connection_handling.rb +98 -0
  80. data/lib/active_record/core.rb +428 -0
  81. data/lib/active_record/counter_cache.rb +106 -108
  82. data/lib/active_record/dynamic_matchers.rb +110 -63
  83. data/lib/active_record/errors.rb +25 -8
  84. data/lib/active_record/explain.rb +8 -58
  85. data/lib/active_record/explain_subscriber.rb +6 -3
  86. data/lib/active_record/fixture_set/file.rb +56 -0
  87. data/lib/active_record/fixtures.rb +146 -148
  88. data/lib/active_record/inheritance.rb +77 -59
  89. data/lib/active_record/integration.rb +5 -5
  90. data/lib/active_record/locale/en.yml +8 -1
  91. data/lib/active_record/locking/optimistic.rb +38 -42
  92. data/lib/active_record/locking/pessimistic.rb +4 -4
  93. data/lib/active_record/log_subscriber.rb +19 -9
  94. data/lib/active_record/migration.rb +318 -153
  95. data/lib/active_record/migration/command_recorder.rb +90 -31
  96. data/lib/active_record/migration/join_table.rb +15 -0
  97. data/lib/active_record/model_schema.rb +69 -92
  98. data/lib/active_record/nested_attributes.rb +113 -148
  99. data/lib/active_record/null_relation.rb +65 -0
  100. data/lib/active_record/persistence.rb +188 -97
  101. data/lib/active_record/query_cache.rb +18 -36
  102. data/lib/active_record/querying.rb +19 -15
  103. data/lib/active_record/railtie.rb +91 -36
  104. data/lib/active_record/railties/console_sandbox.rb +0 -2
  105. data/lib/active_record/railties/controller_runtime.rb +2 -2
  106. data/lib/active_record/railties/databases.rake +90 -309
  107. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  108. data/lib/active_record/readonly_attributes.rb +7 -3
  109. data/lib/active_record/reflection.rb +72 -56
  110. data/lib/active_record/relation.rb +241 -157
  111. data/lib/active_record/relation/batches.rb +25 -22
  112. data/lib/active_record/relation/calculations.rb +143 -121
  113. data/lib/active_record/relation/delegation.rb +96 -18
  114. data/lib/active_record/relation/finder_methods.rb +117 -183
  115. data/lib/active_record/relation/merger.rb +133 -0
  116. data/lib/active_record/relation/predicate_builder.rb +90 -42
  117. data/lib/active_record/relation/query_methods.rb +666 -136
  118. data/lib/active_record/relation/spawn_methods.rb +43 -150
  119. data/lib/active_record/result.rb +33 -6
  120. data/lib/active_record/sanitization.rb +24 -50
  121. data/lib/active_record/schema.rb +19 -12
  122. data/lib/active_record/schema_dumper.rb +31 -39
  123. data/lib/active_record/schema_migration.rb +36 -0
  124. data/lib/active_record/scoping.rb +0 -124
  125. data/lib/active_record/scoping/default.rb +48 -45
  126. data/lib/active_record/scoping/named.rb +74 -103
  127. data/lib/active_record/serialization.rb +6 -2
  128. data/lib/active_record/serializers/xml_serializer.rb +9 -15
  129. data/lib/active_record/store.rb +119 -15
  130. data/lib/active_record/tasks/database_tasks.rb +158 -0
  131. data/lib/active_record/tasks/mysql_database_tasks.rb +138 -0
  132. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  133. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  134. data/lib/active_record/test_case.rb +61 -38
  135. data/lib/active_record/timestamp.rb +8 -9
  136. data/lib/active_record/transactions.rb +65 -51
  137. data/lib/active_record/validations.rb +17 -15
  138. data/lib/active_record/validations/associated.rb +20 -14
  139. data/lib/active_record/validations/presence.rb +65 -0
  140. data/lib/active_record/validations/uniqueness.rb +93 -52
  141. data/lib/active_record/version.rb +4 -4
  142. data/lib/rails/generators/active_record.rb +3 -5
  143. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -7
  144. data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
  145. data/lib/rails/generators/active_record/model/model_generator.rb +4 -3
  146. data/lib/rails/generators/active_record/model/templates/model.rb +1 -6
  147. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  148. metadata +53 -46
  149. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  150. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  151. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  152. data/lib/active_record/dynamic_finder_match.rb +0 -68
  153. data/lib/active_record/dynamic_scope_match.rb +0 -23
  154. data/lib/active_record/fixtures/file.rb +0 -65
  155. data/lib/active_record/identity_map.rb +0 -162
  156. data/lib/active_record/observer.rb +0 -121
  157. data/lib/active_record/session_store.rb +0 -360
  158. data/lib/rails/generators/active_record/migration.rb +0 -15
  159. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  160. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  161. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  162. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,180 +1,73 @@
1
- require 'active_support/core_ext/object/blank'
1
+ require 'active_support/core_ext/hash/except'
2
+ require 'active_support/core_ext/hash/slice'
3
+ require 'active_record/relation/merger'
2
4
 
3
5
  module ActiveRecord
4
6
  module SpawnMethods
5
- def merge(r)
6
- return self unless r
7
- return to_a & r if r.is_a?(Array)
8
7
 
9
- merged_relation = clone
10
-
11
- r = r.with_default_scope if r.default_scoped? && r.klass != klass
12
-
13
- Relation::ASSOCIATION_METHODS.each do |method|
14
- value = r.send(:"#{method}_values")
15
-
16
- unless value.empty?
17
- if method == :includes
18
- merged_relation = merged_relation.includes(value)
19
- else
20
- merge_relation_method(merged_relation, method, value)
21
- end
22
- end
23
- end
24
-
25
- (Relation::MULTI_VALUE_METHODS - [:joins, :where, :order]).each do |method|
26
- value = r.send(:"#{method}_values")
27
- merge_relation_method(merged_relation, method, value) if value.present?
28
- end
29
-
30
- merge_joins(merged_relation, r)
31
-
32
- merged_wheres = @where_values + r.where_values
33
-
34
- unless @where_values.empty?
35
- # Remove duplicate ARel attributes. Last one wins.
36
- seen = Hash.new { |h,table| h[table] = {} }
37
- merged_wheres = merged_wheres.reverse.reject { |w|
38
- nuke = false
39
- if w.respond_to?(:operator) && w.operator == :== &&
40
- w.left.respond_to?(:relation)
41
- name = w.left.name
42
- table = w.left.relation.name
43
- nuke = seen[table][name]
44
- seen[table][name] = true
45
- end
46
- nuke
47
- }.reverse
48
- end
49
-
50
- merged_relation.where_values = merged_wheres
8
+ # This is overridden by Associations::CollectionProxy
9
+ def spawn #:nodoc:
10
+ clone
11
+ end
51
12
 
52
- (Relation::SINGLE_VALUE_METHODS - [:lock, :create_with, :reordering]).each do |method|
53
- value = r.send(:"#{method}_value")
54
- merged_relation.send(:"#{method}_value=", value) unless value.nil?
13
+ # Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an <tt>ActiveRecord::Relation</tt>.
14
+ # Returns an array representing the intersection of the resulting records with <tt>other</tt>, if <tt>other</tt> is an array.
15
+ # Post.where(published: true).joins(:comments).merge( Comment.where(spam: false) )
16
+ # # Performs a single join query with both where conditions.
17
+ #
18
+ # recent_posts = Post.order('created_at DESC').first(5)
19
+ # Post.where(published: true).merge(recent_posts)
20
+ # # Returns the intersection of all published posts with the 5 most recently created posts.
21
+ # # (This is just an example. You'd probably want to do this with a single query!)
22
+ #
23
+ # Procs will be evaluated by merge:
24
+ #
25
+ # Post.where(published: true).merge(-> { joins(:comments) })
26
+ # # => Post.where(published: true).joins(:comments)
27
+ #
28
+ # This is mainly intended for sharing common conditions between multiple associations.
29
+ def merge(other)
30
+ if other.is_a?(Array)
31
+ to_a & other
32
+ elsif other
33
+ spawn.merge!(other)
34
+ else
35
+ self
55
36
  end
37
+ end
56
38
 
57
- merged_relation.lock_value = r.lock_value unless merged_relation.lock_value
58
-
59
- merged_relation = merged_relation.create_with(r.create_with_value) unless r.create_with_value.empty?
60
-
61
- if (r.reordering_value)
62
- # override any order specified in the original relation
63
- merged_relation.reordering_value = true
64
- merged_relation.order_values = r.order_values
39
+ def merge!(other) # :nodoc:
40
+ if !other.is_a?(Relation) && other.respond_to?(:to_proc)
41
+ instance_exec(&other)
65
42
  else
66
- # merge in order_values from r
67
- merged_relation.order_values += r.order_values
43
+ klass = other.is_a?(Hash) ? Relation::HashMerger : Relation::Merger
44
+ klass.new(self, other).merge
68
45
  end
69
-
70
- # Apply scope extension modules
71
- merged_relation.send :apply_modules, r.extensions
72
-
73
- merged_relation
74
46
  end
75
47
 
76
48
  # Removes from the query the condition(s) specified in +skips+.
77
49
  #
78
- # Example:
79
- #
80
50
  # Post.order('id asc').except(:order) # discards the order condition
81
51
  # Post.where('id > 10').order('id asc').except(:where) # discards the where condition but keeps the order
82
- #
83
52
  def except(*skips)
84
- result = self.class.new(@klass, table)
85
- result.default_scoped = default_scoped
86
-
87
- ((Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS) - skips).each do |method|
88
- result.send(:"#{method}_values=", send(:"#{method}_values"))
89
- end
90
-
91
- (Relation::SINGLE_VALUE_METHODS - skips).each do |method|
92
- result.send(:"#{method}_value=", send(:"#{method}_value"))
93
- end
94
-
95
- # Apply scope extension modules
96
- result.send(:apply_modules, extensions)
97
-
98
- result
53
+ relation_with values.except(*skips)
99
54
  end
100
55
 
101
56
  # Removes any condition from the query other than the one(s) specified in +onlies+.
102
57
  #
103
- # Example:
104
- #
105
58
  # Post.order('id asc').only(:where) # discards the order condition
106
59
  # Post.order('id asc').only(:where, :order) # uses the specified order
107
- #
108
60
  def only(*onlies)
109
- result = self.class.new(@klass, table)
110
- result.default_scoped = default_scoped
111
-
112
- ((Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS) & onlies).each do |method|
113
- result.send(:"#{method}_values=", send(:"#{method}_values"))
114
- end
115
-
116
- (Relation::SINGLE_VALUE_METHODS & onlies).each do |method|
117
- result.send(:"#{method}_value=", send(:"#{method}_value"))
118
- end
119
-
120
- # Apply scope extension modules
121
- result.send(:apply_modules, extensions)
122
-
123
- result
124
- end
125
-
126
- VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset, :extend,
127
- :order, :select, :readonly, :group, :having, :from, :lock ]
128
-
129
- def apply_finder_options(options)
130
- relation = clone
131
- return relation unless options
132
-
133
- options.assert_valid_keys(VALID_FIND_OPTIONS)
134
- finders = options.dup
135
- finders.delete_if { |key, value| value.nil? && key != :limit }
136
-
137
- ([:joins, :select, :group, :order, :having, :limit, :offset, :from, :lock, :readonly] & finders.keys).each do |finder|
138
- relation = relation.send(finder, finders[finder])
139
- end
140
-
141
- relation = relation.where(finders[:conditions]) if options.has_key?(:conditions)
142
- relation = relation.includes(finders[:include]) if options.has_key?(:include)
143
- relation = relation.extending(finders[:extend]) if options.has_key?(:extend)
144
-
145
- relation
61
+ relation_with values.slice(*onlies)
146
62
  end
147
63
 
148
64
  private
149
65
 
150
- def merge_joins(relation, other)
151
- values = other.joins_values
152
- return if values.blank?
153
-
154
- if other.klass >= relation.klass
155
- relation.joins_values += values
156
- else
157
- joins_dependency, rest = values.partition do |join|
158
- case join
159
- when Hash, Symbol, Array
160
- true
161
- else
162
- false
163
- end
164
- end
165
-
166
- join_dependency = ActiveRecord::Associations::JoinDependency.new(
167
- other.klass,
168
- joins_dependency,
169
- []
170
- )
171
-
172
- relation.joins_values += join_dependency.join_associations + rest
173
- end
174
- end
175
-
176
- def merge_relation_method(relation, method, value)
177
- relation.send(:"#{method}_values=", relation.send(:"#{method}_values") + value)
66
+ def relation_with(values) # :nodoc:
67
+ result = Relation.new(klass, table, values)
68
+ result.default_scoped = default_scoped
69
+ result.extend(*extending_values) if extending_values.any?
70
+ result
178
71
  end
179
72
  end
180
73
  end
@@ -8,12 +8,13 @@ module ActiveRecord
8
8
  class Result
9
9
  include Enumerable
10
10
 
11
- attr_reader :columns, :rows
11
+ attr_reader :columns, :rows, :column_types
12
12
 
13
- def initialize(columns, rows)
14
- @columns = columns
15
- @rows = rows
16
- @hash_rows = nil
13
+ def initialize(columns, rows, column_types = {})
14
+ @columns = columns
15
+ @rows = rows
16
+ @hash_rows = nil
17
+ @column_types = column_types
17
18
  end
18
19
 
19
20
  def each
@@ -24,12 +25,38 @@ module ActiveRecord
24
25
  hash_rows
25
26
  end
26
27
 
28
+ alias :map! :map
29
+ alias :collect! :map
30
+
31
+ # Returns true if there are no records.
32
+ def empty?
33
+ rows.empty?
34
+ end
35
+
36
+ def to_ary
37
+ hash_rows
38
+ end
39
+
40
+ def [](idx)
41
+ hash_rows[idx]
42
+ end
43
+
44
+ def last
45
+ hash_rows.last
46
+ end
47
+
48
+ def initialize_copy(other)
49
+ @columns = columns.dup
50
+ @rows = rows.dup
51
+ @hash_rows = nil
52
+ end
53
+
27
54
  private
28
55
  def hash_rows
29
56
  @hash_rows ||=
30
57
  begin
31
58
  # We freeze the strings to prevent them getting duped when
32
- # used as keys in ActiveRecord::Model's @attributes hash
59
+ # used as keys in ActiveRecord::Base's @attributes hash
33
60
  columns = @columns.map { |c| c.dup.freeze }
34
61
  @rows.map { |row|
35
62
  Hash[columns.zip(row)]
@@ -1,5 +1,3 @@
1
- require 'active_support/concern'
2
-
3
1
  module ActiveRecord
4
2
  module Sanitization
5
3
  extend ActiveSupport::Concern
@@ -19,7 +17,7 @@ module ActiveRecord
19
17
  # Accepts an array, hash, or string of SQL conditions and sanitizes
20
18
  # them into a valid SQL fragment for a WHERE clause.
21
19
  # ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'"
22
- # { :name => "foo'bar", :group_id => 4 } returns "name='foo''bar' and group_id='4'"
20
+ # { name: "foo'bar", group_id: 4 } returns "name='foo''bar' and group_id='4'"
23
21
  # "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'"
24
22
  def sanitize_sql_for_conditions(condition, table_name = self.table_name)
25
23
  return nil if condition.blank?
@@ -34,12 +32,12 @@ module ActiveRecord
34
32
 
35
33
  # Accepts an array, hash, or string of SQL conditions and sanitizes
36
34
  # them into a valid SQL fragment for a SET clause.
37
- # { :name => nil, :group_id => 4 } returns "name = NULL , group_id='4'"
38
- def sanitize_sql_for_assignment(assignments)
35
+ # { name: nil, group_id: 4 } returns "name = NULL , group_id='4'"
36
+ def sanitize_sql_for_assignment(assignments, default_table_name = self.table_name)
39
37
  case assignments
40
- when Array; sanitize_sql_array(assignments)
41
- when Hash; sanitize_sql_hash_for_assignment(assignments)
42
- else assignments
38
+ when Array; sanitize_sql_array(assignments)
39
+ when Hash; sanitize_sql_hash_for_assignment(assignments, default_table_name)
40
+ else assignments
43
41
  end
44
42
  end
45
43
 
@@ -48,17 +46,17 @@ module ActiveRecord
48
46
  # aggregate attribute values.
49
47
  # Given:
50
48
  # class Person < ActiveRecord::Base
51
- # composed_of :address, :class_name => "Address",
52
- # :mapping => [%w(address_street street), %w(address_city city)]
49
+ # composed_of :address, class_name: "Address",
50
+ # mapping: [%w(address_street street), %w(address_city city)]
53
51
  # end
54
52
  # Then:
55
- # { :address => Address.new("813 abc st.", "chicago") }
56
- # # => { :address_street => "813 abc st.", :address_city => "chicago" }
53
+ # { address: Address.new("813 abc st.", "chicago") }
54
+ # # => { address_street: "813 abc st.", address_city: "chicago" }
57
55
  def expand_hash_conditions_for_aggregates(attrs)
58
56
  expanded_attrs = {}
59
57
  attrs.each do |attr, value|
60
- unless (aggregation = reflect_on_aggregation(attr.to_sym)).nil?
61
- mapping = aggregate_mapping(aggregation)
58
+ if aggregation = reflect_on_aggregation(attr.to_sym)
59
+ mapping = aggregation.mapping
62
60
  mapping.each do |field_attr, aggregate_attr|
63
61
  if mapping.size == 1 && !value.respond_to?(aggregate_attr)
64
62
  expanded_attrs[field_attr] = value
@@ -74,35 +72,35 @@ module ActiveRecord
74
72
  end
75
73
 
76
74
  # Sanitizes a hash of attribute/value pairs into SQL conditions for a WHERE clause.
77
- # { :name => "foo'bar", :group_id => 4 }
75
+ # { name: "foo'bar", group_id: 4 }
78
76
  # # => "name='foo''bar' and group_id= 4"
79
- # { :status => nil, :group_id => [1,2,3] }
77
+ # { status: nil, group_id: [1,2,3] }
80
78
  # # => "status IS NULL and group_id IN (1,2,3)"
81
- # { :age => 13..18 }
79
+ # { age: 13..18 }
82
80
  # # => "age BETWEEN 13 AND 18"
83
81
  # { 'other_records.id' => 7 }
84
82
  # # => "`other_records`.`id` = 7"
85
- # { :other_records => { :id => 7 } }
83
+ # { other_records: { id: 7 } }
86
84
  # # => "`other_records`.`id` = 7"
87
85
  # And for value objects on a composed_of relationship:
88
- # { :address => Address.new("123 abc st.", "chicago") }
86
+ # { address: Address.new("123 abc st.", "chicago") }
89
87
  # # => "address_street='123 abc st.' and address_city='chicago'"
90
88
  def sanitize_sql_hash_for_conditions(attrs, default_table_name = self.table_name)
91
89
  attrs = expand_hash_conditions_for_aggregates(attrs)
92
90
 
93
- table = Arel::Table.new(table_name).alias(default_table_name)
94
- PredicateBuilder.build_from_hash(arel_engine, attrs, table).map { |b|
91
+ table = Arel::Table.new(table_name, arel_engine).alias(default_table_name)
92
+ PredicateBuilder.build_from_hash(self.class, attrs, table).map { |b|
95
93
  connection.visitor.accept b
96
94
  }.join(' AND ')
97
95
  end
98
96
  alias_method :sanitize_sql_hash, :sanitize_sql_hash_for_conditions
99
97
 
100
98
  # Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.
101
- # { :status => nil, :group_id => 1 }
99
+ # { status: nil, group_id: 1 }
102
100
  # # => "status = NULL , group_id = 1"
103
- def sanitize_sql_hash_for_assignment(attrs)
101
+ def sanitize_sql_hash_for_assignment(attrs, table)
104
102
  attrs.map do |attr, value|
105
- "#{connection.quote_column_name(attr)} = #{quote_bound_value(value)}"
103
+ "#{connection.quote_table_name_for_assignment(table, attr)} = #{quote_bound_value(value)}"
106
104
  end.join(', ')
107
105
  end
108
106
 
@@ -143,23 +141,6 @@ module ActiveRecord
143
141
  end
144
142
  end
145
143
 
146
- def expand_range_bind_variables(bind_vars) #:nodoc:
147
- expanded = []
148
-
149
- bind_vars.each do |var|
150
- next if var.is_a?(Hash)
151
-
152
- if var.is_a?(Range)
153
- expanded << var.first
154
- expanded << var.last
155
- else
156
- expanded << var
157
- end
158
- end
159
-
160
- expanded
161
- end
162
-
163
144
  def quote_bound_value(value, c = connection) #:nodoc:
164
145
  if value.respond_to?(:map) && !value.acts_like?(:string)
165
146
  if value.respond_to?(:empty?) && value.empty?
@@ -180,15 +161,8 @@ module ActiveRecord
180
161
  end
181
162
 
182
163
  # TODO: Deprecate this
183
- def quoted_id #:nodoc:
184
- quote_value(id, column_for_attribute(self.class.primary_key))
185
- end
186
-
187
- private
188
-
189
- # Quote strings appropriately for SQL statements.
190
- def quote_value(value, column = nil)
191
- self.class.connection.quote(value, column)
164
+ def quoted_id
165
+ self.class.quote_value(id, column_for_attribute(self.class.primary_key))
192
166
  end
193
167
  end
194
168
  end
@@ -1,4 +1,3 @@
1
- require 'active_support/core_ext/object/blank'
2
1
 
3
2
  module ActiveRecord
4
3
  # = Active Record Schema
@@ -12,16 +11,16 @@ module ActiveRecord
12
11
  #
13
12
  # ActiveRecord::Schema.define do
14
13
  # create_table :authors do |t|
15
- # t.string :name, :null => false
14
+ # t.string :name, null: false
16
15
  # end
17
16
  #
18
17
  # add_index :authors, :name, :unique
19
18
  #
20
19
  # create_table :posts do |t|
21
- # t.integer :author_id, :null => false
20
+ # t.integer :author_id, null: false
22
21
  # t.string :subject
23
22
  # t.text :body
24
- # t.boolean :private, :default => false
23
+ # t.boolean :private, default: false
25
24
  # end
26
25
  #
27
26
  # add_index :posts, :author_id
@@ -30,10 +29,24 @@ module ActiveRecord
30
29
  # ActiveRecord::Schema is only supported by database adapters that also
31
30
  # support migrations, the two features being very similar.
32
31
  class Schema < Migration
32
+
33
+ # Returns the migrations paths.
34
+ #
35
+ # ActiveRecord::Schema.new.migrations_paths
36
+ # # => ["db/migrate"] # Rails migration path by default.
33
37
  def migrations_paths
34
38
  ActiveRecord::Migrator.migrations_paths
35
39
  end
36
40
 
41
+ def define(info, &block) # :nodoc:
42
+ instance_eval(&block)
43
+
44
+ unless info[:version].blank?
45
+ initialize_schema_migrations_table
46
+ assume_migrated_upto_version(info[:version], migrations_paths)
47
+ end
48
+ end
49
+
37
50
  # Eval the given block. All methods available to the current connection
38
51
  # adapter are available within the block, so you can easily use the
39
52
  # database definition DSL to build up your schema (+create_table+,
@@ -42,17 +55,11 @@ module ActiveRecord
42
55
  # The +info+ hash is optional, and if given is used to define metadata
43
56
  # about the current schema (currently, only the schema's version):
44
57
  #
45
- # ActiveRecord::Schema.define(:version => 20380119000001) do
58
+ # ActiveRecord::Schema.define(version: 20380119000001) do
46
59
  # ...
47
60
  # end
48
61
  def self.define(info={}, &block)
49
- schema = new
50
- schema.instance_eval(&block)
51
-
52
- unless info[:version].blank?
53
- initialize_schema_migrations_table
54
- assume_migrated_upto_version(info[:version], schema.migrations_paths)
55
- end
62
+ new.define(info, &block)
56
63
  end
57
64
  end
58
65
  end