activerecord 5.0.7 → 5.1.7

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 (219) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +657 -2080
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +28 -28
  6. data/examples/simple.rb +3 -3
  7. data/lib/active_record/aggregations.rb +244 -244
  8. data/lib/active_record/association_relation.rb +5 -5
  9. data/lib/active_record/associations/alias_tracker.rb +10 -11
  10. data/lib/active_record/associations/association.rb +23 -5
  11. data/lib/active_record/associations/association_scope.rb +95 -81
  12. data/lib/active_record/associations/belongs_to_association.rb +7 -4
  13. data/lib/active_record/associations/builder/belongs_to.rb +30 -16
  14. data/lib/active_record/associations/builder/collection_association.rb +1 -2
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
  16. data/lib/active_record/associations/collection_association.rb +36 -205
  17. data/lib/active_record/associations/collection_proxy.rb +132 -63
  18. data/lib/active_record/associations/has_many_association.rb +10 -19
  19. data/lib/active_record/associations/has_many_through_association.rb +12 -4
  20. data/lib/active_record/associations/has_one_association.rb +24 -28
  21. data/lib/active_record/associations/has_one_through_association.rb +5 -1
  22. data/lib/active_record/associations/join_dependency/join_association.rb +4 -28
  23. data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
  24. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  25. data/lib/active_record/associations/join_dependency.rb +121 -118
  26. data/lib/active_record/associations/preloader/association.rb +64 -64
  27. data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
  28. data/lib/active_record/associations/preloader/collection_association.rb +6 -6
  29. data/lib/active_record/associations/preloader/has_many.rb +0 -2
  30. data/lib/active_record/associations/preloader/singular_association.rb +6 -8
  31. data/lib/active_record/associations/preloader/through_association.rb +41 -41
  32. data/lib/active_record/associations/preloader.rb +94 -94
  33. data/lib/active_record/associations/singular_association.rb +8 -25
  34. data/lib/active_record/associations/through_association.rb +2 -5
  35. data/lib/active_record/associations.rb +1591 -1562
  36. data/lib/active_record/attribute/user_provided_default.rb +4 -2
  37. data/lib/active_record/attribute.rb +98 -71
  38. data/lib/active_record/attribute_assignment.rb +61 -61
  39. data/lib/active_record/attribute_decorators.rb +35 -13
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +229 -46
  42. data/lib/active_record/attribute_methods/primary_key.rb +74 -73
  43. data/lib/active_record/attribute_methods/read.rb +39 -35
  44. data/lib/active_record/attribute_methods/serialization.rb +7 -7
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
  46. data/lib/active_record/attribute_methods/write.rb +30 -33
  47. data/lib/active_record/attribute_methods.rb +56 -65
  48. data/lib/active_record/attribute_mutation_tracker.rb +63 -11
  49. data/lib/active_record/attribute_set/builder.rb +27 -33
  50. data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
  51. data/lib/active_record/attribute_set.rb +9 -6
  52. data/lib/active_record/attributes.rb +22 -22
  53. data/lib/active_record/autosave_association.rb +18 -13
  54. data/lib/active_record/base.rb +24 -22
  55. data/lib/active_record/callbacks.rb +56 -14
  56. data/lib/active_record/coders/yaml_column.rb +9 -11
  57. data/lib/active_record/collection_cache_key.rb +3 -4
  58. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +330 -284
  59. data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
  60. data/lib/active_record/connection_adapters/abstract/database_statements.rb +39 -37
  61. data/lib/active_record/connection_adapters/abstract/query_cache.rb +32 -27
  62. data/lib/active_record/connection_adapters/abstract/quoting.rb +62 -51
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +10 -20
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +74 -79
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +120 -100
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +49 -43
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +165 -135
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +404 -424
  70. data/lib/active_record/connection_adapters/column.rb +26 -4
  71. data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
  72. data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -28
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +43 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +7 -6
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +23 -27
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +32 -53
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +19 -9
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
  86. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
  90. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
  91. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +0 -10
  92. data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
  93. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
  96. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +32 -30
  97. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
  98. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
  99. data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
  100. data/lib/active_record/connection_adapters/postgresql/quoting.rb +40 -35
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +182 -222
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +6 -4
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +7 -5
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +198 -167
  108. data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
  110. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -19
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
  113. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
  114. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
  115. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +32 -0
  116. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +184 -167
  117. data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
  118. data/lib/active_record/connection_handling.rb +14 -26
  119. data/lib/active_record/core.rb +109 -93
  120. data/lib/active_record/counter_cache.rb +60 -13
  121. data/lib/active_record/define_callbacks.rb +20 -0
  122. data/lib/active_record/dynamic_matchers.rb +80 -79
  123. data/lib/active_record/enum.rb +8 -6
  124. data/lib/active_record/errors.rb +64 -15
  125. data/lib/active_record/explain.rb +1 -2
  126. data/lib/active_record/explain_registry.rb +1 -1
  127. data/lib/active_record/explain_subscriber.rb +7 -4
  128. data/lib/active_record/fixture_set/file.rb +11 -8
  129. data/lib/active_record/fixtures.rb +66 -53
  130. data/lib/active_record/gem_version.rb +1 -1
  131. data/lib/active_record/inheritance.rb +93 -79
  132. data/lib/active_record/integration.rb +7 -7
  133. data/lib/active_record/internal_metadata.rb +3 -16
  134. data/lib/active_record/legacy_yaml_adapter.rb +1 -1
  135. data/lib/active_record/locking/optimistic.rb +69 -74
  136. data/lib/active_record/locking/pessimistic.rb +10 -1
  137. data/lib/active_record/log_subscriber.rb +23 -28
  138. data/lib/active_record/migration/command_recorder.rb +94 -94
  139. data/lib/active_record/migration/compatibility.rb +100 -47
  140. data/lib/active_record/migration/join_table.rb +6 -6
  141. data/lib/active_record/migration.rb +153 -155
  142. data/lib/active_record/model_schema.rb +94 -107
  143. data/lib/active_record/nested_attributes.rb +200 -199
  144. data/lib/active_record/null_relation.rb +11 -34
  145. data/lib/active_record/persistence.rb +65 -50
  146. data/lib/active_record/query_cache.rb +2 -6
  147. data/lib/active_record/querying.rb +3 -4
  148. data/lib/active_record/railtie.rb +16 -17
  149. data/lib/active_record/railties/controller_runtime.rb +6 -2
  150. data/lib/active_record/railties/databases.rake +105 -133
  151. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  152. data/lib/active_record/readonly_attributes.rb +2 -2
  153. data/lib/active_record/reflection.rb +154 -108
  154. data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
  155. data/lib/active_record/relation/batches.rb +80 -51
  156. data/lib/active_record/relation/calculations.rb +169 -162
  157. data/lib/active_record/relation/delegation.rb +32 -31
  158. data/lib/active_record/relation/finder_methods.rb +197 -231
  159. data/lib/active_record/relation/merger.rb +58 -62
  160. data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
  161. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
  162. data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
  163. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
  164. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
  165. data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
  166. data/lib/active_record/relation/predicate_builder.rb +92 -89
  167. data/lib/active_record/relation/query_attribute.rb +1 -1
  168. data/lib/active_record/relation/query_methods.rb +255 -293
  169. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  170. data/lib/active_record/relation/spawn_methods.rb +4 -5
  171. data/lib/active_record/relation/where_clause.rb +80 -65
  172. data/lib/active_record/relation/where_clause_factory.rb +47 -8
  173. data/lib/active_record/relation.rb +93 -119
  174. data/lib/active_record/result.rb +41 -32
  175. data/lib/active_record/runtime_registry.rb +3 -3
  176. data/lib/active_record/sanitization.rb +176 -192
  177. data/lib/active_record/schema.rb +3 -3
  178. data/lib/active_record/schema_dumper.rb +15 -38
  179. data/lib/active_record/schema_migration.rb +8 -4
  180. data/lib/active_record/scoping/default.rb +90 -90
  181. data/lib/active_record/scoping/named.rb +11 -11
  182. data/lib/active_record/scoping.rb +6 -6
  183. data/lib/active_record/secure_token.rb +2 -2
  184. data/lib/active_record/statement_cache.rb +13 -15
  185. data/lib/active_record/store.rb +31 -32
  186. data/lib/active_record/suppressor.rb +2 -1
  187. data/lib/active_record/table_metadata.rb +9 -5
  188. data/lib/active_record/tasks/database_tasks.rb +65 -55
  189. data/lib/active_record/tasks/mysql_database_tasks.rb +76 -73
  190. data/lib/active_record/tasks/postgresql_database_tasks.rb +72 -47
  191. data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
  192. data/lib/active_record/timestamp.rb +46 -25
  193. data/lib/active_record/touch_later.rb +1 -2
  194. data/lib/active_record/transactions.rb +97 -109
  195. data/lib/active_record/type/adapter_specific_registry.rb +46 -42
  196. data/lib/active_record/type/decimal_without_scale.rb +13 -0
  197. data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
  198. data/lib/active_record/type/internal/abstract_json.rb +4 -0
  199. data/lib/active_record/type/serialized.rb +14 -8
  200. data/lib/active_record/type/text.rb +9 -0
  201. data/lib/active_record/type/time.rb +0 -1
  202. data/lib/active_record/type/type_map.rb +11 -15
  203. data/lib/active_record/type/unsigned_integer.rb +15 -0
  204. data/lib/active_record/type.rb +17 -13
  205. data/lib/active_record/type_caster/connection.rb +8 -6
  206. data/lib/active_record/type_caster/map.rb +3 -1
  207. data/lib/active_record/type_caster.rb +2 -2
  208. data/lib/active_record/validations/associated.rb +1 -1
  209. data/lib/active_record/validations/presence.rb +2 -2
  210. data/lib/active_record/validations/uniqueness.rb +8 -39
  211. data/lib/active_record/validations.rb +4 -4
  212. data/lib/active_record/version.rb +1 -1
  213. data/lib/active_record.rb +20 -20
  214. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
  215. data/lib/rails/generators/active_record/migration.rb +1 -1
  216. data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
  217. data/lib/rails/generators/active_record.rb +4 -4
  218. metadata +24 -13
  219. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -1,4 +1,4 @@
1
- require 'stringio'
1
+ require "stringio"
2
2
 
3
3
  module ActiveRecord
4
4
  # = Active Record Schema Dumper
@@ -17,7 +17,7 @@ module ActiveRecord
17
17
  @@ignore_tables = []
18
18
 
19
19
  class << self
20
- def dump(connection=ActiveRecord::Base.connection, stream=STDOUT, config = ActiveRecord::Base)
20
+ def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
21
21
  new(connection, generate_options(config)).dump(stream)
22
22
  stream
23
23
  end
@@ -85,7 +85,7 @@ HEADER
85
85
  end
86
86
 
87
87
  def tables(stream)
88
- sorted_tables = @connection.data_sources.sort - @connection.views
88
+ sorted_tables = @connection.tables.sort
89
89
 
90
90
  sorted_tables.each do |table_name|
91
91
  table(table_name, stream) unless ignored?(table_name)
@@ -111,13 +111,11 @@ HEADER
111
111
 
112
112
  case pk
113
113
  when String
114
- tbl.print ", primary_key: #{pk.inspect}" unless pk == 'id'
114
+ tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
115
115
  pkcol = columns.detect { |c| c.name == pk }
116
116
  pkcolspec = @connection.column_spec_for_primary_key(pkcol)
117
117
  if pkcolspec.present?
118
- pkcolspec.each do |key, value|
119
- tbl.print ", #{key}: #{value}"
120
- end
118
+ tbl.print ", #{format_colspec(pkcolspec)}"
121
119
  end
122
120
  when Array
123
121
  tbl.print ", primary_key: #{pk.inspect}"
@@ -134,37 +132,12 @@ HEADER
134
132
  tbl.puts " do |t|"
135
133
 
136
134
  # then dump all non-primary key columns
137
- column_specs = columns.map do |column|
135
+ columns.each do |column|
138
136
  raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
139
137
  next if column.name == pk
140
- @connection.column_spec(column)
141
- end.compact
142
-
143
- # find all migration keys used in this table
144
- keys = @connection.migration_keys
145
-
146
- # figure out the lengths for each column based on above keys
147
- lengths = keys.map { |key|
148
- column_specs.map { |spec|
149
- spec[key] ? spec[key].length + 2 : 0
150
- }.max
151
- }
152
-
153
- # the string we're going to sprintf our values against, with standardized column widths
154
- format_string = lengths.map{ |len| "%-#{len}s" }
155
-
156
- # find the max length for the 'type' column, which is special
157
- type_length = column_specs.map{ |column| column[:type].length }.max
158
-
159
- # add column type definition to our format string
160
- format_string.unshift " t.%-#{type_length}s "
161
-
162
- format_string *= ''
163
-
164
- column_specs.each do |colspec|
165
- values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
166
- values.unshift colspec[:type]
167
- tbl.print((format_string % values).gsub(/,\s*$/, ''))
138
+ type, colspec = @connection.column_spec(column)
139
+ tbl.print " t.#{type} #{column.name.inspect}"
140
+ tbl.print ", #{format_colspec(colspec)}" if colspec.present?
168
141
  tbl.puts
169
142
  end
170
143
 
@@ -189,7 +162,7 @@ HEADER
189
162
  if (indexes = @connection.indexes(table)).any?
190
163
  add_index_statements = indexes.map do |index|
191
164
  table_name = remove_prefix_and_suffix(index.table).inspect
192
- " add_index #{([table_name]+index_parts(index)).join(', ')}"
165
+ " add_index #{([table_name] + index_parts(index)).join(', ')}"
193
166
  end
194
167
 
195
168
  stream.puts add_index_statements.sort.join("\n")
@@ -215,7 +188,7 @@ HEADER
215
188
  index_parts << "length: { #{format_options(index.lengths)} }" if index.lengths.present?
216
189
  index_parts << "order: { #{format_options(index.orders)} }" if index.orders.present?
217
190
  index_parts << "where: #{index.where.inspect}" if index.where
218
- index_parts << "using: #{index.using.inspect}" if index.using
191
+ index_parts << "using: #{index.using.inspect}" if !@connection.default_index_type?(index)
219
192
  index_parts << "type: #{index.type.inspect}" if index.type
220
193
  index_parts << "comment: #{index.comment.inspect}" if index.comment
221
194
  index_parts
@@ -251,6 +224,10 @@ HEADER
251
224
  end
252
225
  end
253
226
 
227
+ def format_colspec(colspec)
228
+ colspec.map { |key, value| "#{key}: #{value}" }.join(", ")
229
+ end
230
+
254
231
  def format_options(options)
255
232
  options.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
256
233
  end
@@ -1,5 +1,5 @@
1
- require 'active_record/scoping/default'
2
- require 'active_record/scoping/named'
1
+ require "active_record/scoping/default"
2
+ require "active_record/scoping/named"
3
3
 
4
4
  module ActiveRecord
5
5
  # This class is used to create a table that keeps track of which migrations
@@ -17,7 +17,7 @@ module ActiveRecord
17
17
  end
18
18
 
19
19
  def table_exists?
20
- ActiveSupport::Deprecation.silence { connection.table_exists?(table_name) }
20
+ connection.table_exists?(table_name)
21
21
  end
22
22
 
23
23
  def create_table
@@ -39,7 +39,11 @@ module ActiveRecord
39
39
  end
40
40
 
41
41
  def normalized_versions
42
- pluck(:version).map { |v| normalize_migration_number v }
42
+ all_versions.map { |v| normalize_migration_number v }
43
+ end
44
+
45
+ def all_versions
46
+ order(:version).pluck(:version)
43
47
  end
44
48
  end
45
49
 
@@ -44,109 +44,109 @@ module ActiveRecord
44
44
  self.current_scope = nil
45
45
  end
46
46
 
47
- protected
47
+ private
48
+
49
+ # Use this macro in your model to set a default scope for all operations on
50
+ # the model.
51
+ #
52
+ # class Article < ActiveRecord::Base
53
+ # default_scope { where(published: true) }
54
+ # end
55
+ #
56
+ # Article.all # => SELECT * FROM articles WHERE published = true
57
+ #
58
+ # The #default_scope is also applied while creating/building a record.
59
+ # It is not applied while updating a record.
60
+ #
61
+ # Article.new.published # => true
62
+ # Article.create.published # => true
63
+ #
64
+ # (You can also pass any object which responds to +call+ to the
65
+ # +default_scope+ macro, and it will be called when building the
66
+ # default scope.)
67
+ #
68
+ # If you use multiple #default_scope declarations in your model then
69
+ # they will be merged together:
70
+ #
71
+ # class Article < ActiveRecord::Base
72
+ # default_scope { where(published: true) }
73
+ # default_scope { where(rating: 'G') }
74
+ # end
75
+ #
76
+ # Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
77
+ #
78
+ # This is also the case with inheritance and module includes where the
79
+ # parent or module defines a #default_scope and the child or including
80
+ # class defines a second one.
81
+ #
82
+ # If you need to do more complex things with a default scope, you can
83
+ # alternatively define it as a class method:
84
+ #
85
+ # class Article < ActiveRecord::Base
86
+ # def self.default_scope
87
+ # # Should return a scope, you can call 'super' here etc.
88
+ # end
89
+ # end
90
+ def default_scope(scope = nil) # :doc:
91
+ scope = Proc.new if block_given?
92
+
93
+ if scope.is_a?(Relation) || !scope.respond_to?(:call)
94
+ raise ArgumentError,
95
+ "Support for calling #default_scope without a block is removed. For example instead " \
96
+ "of `default_scope where(color: 'red')`, please use " \
97
+ "`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
98
+ "self.default_scope.)"
99
+ end
48
100
 
49
- # Use this macro in your model to set a default scope for all operations on
50
- # the model.
51
- #
52
- # class Article < ActiveRecord::Base
53
- # default_scope { where(published: true) }
54
- # end
55
- #
56
- # Article.all # => SELECT * FROM articles WHERE published = true
57
- #
58
- # The #default_scope is also applied while creating/building a record.
59
- # It is not applied while updating a record.
60
- #
61
- # Article.new.published # => true
62
- # Article.create.published # => true
63
- #
64
- # (You can also pass any object which responds to +call+ to the
65
- # +default_scope+ macro, and it will be called when building the
66
- # default scope.)
67
- #
68
- # If you use multiple #default_scope declarations in your model then
69
- # they will be merged together:
70
- #
71
- # class Article < ActiveRecord::Base
72
- # default_scope { where(published: true) }
73
- # default_scope { where(rating: 'G') }
74
- # end
75
- #
76
- # Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
77
- #
78
- # This is also the case with inheritance and module includes where the
79
- # parent or module defines a #default_scope and the child or including
80
- # class defines a second one.
81
- #
82
- # If you need to do more complex things with a default scope, you can
83
- # alternatively define it as a class method:
84
- #
85
- # class Article < ActiveRecord::Base
86
- # def self.default_scope
87
- # # Should return a scope, you can call 'super' here etc.
88
- # end
89
- # end
90
- def default_scope(scope = nil)
91
- scope = Proc.new if block_given?
92
-
93
- if scope.is_a?(Relation) || !scope.respond_to?(:call)
94
- raise ArgumentError,
95
- "Support for calling #default_scope without a block is removed. For example instead " \
96
- "of `default_scope where(color: 'red')`, please use " \
97
- "`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
98
- "self.default_scope.)"
101
+ self.default_scopes += [scope]
99
102
  end
100
103
 
101
- self.default_scopes += [scope]
102
- end
103
-
104
- def build_default_scope(base_rel = nil) # :nodoc:
105
- return if abstract_class?
104
+ def build_default_scope(base_rel = nil)
105
+ return if abstract_class?
106
106
 
107
- if self.default_scope_override.nil?
108
- self.default_scope_override = !Base.is_a?(method(:default_scope).owner)
109
- end
107
+ if default_scope_override.nil?
108
+ self.default_scope_override = !Base.is_a?(method(:default_scope).owner)
109
+ end
110
110
 
111
- if self.default_scope_override
112
- # The user has defined their own default scope method, so call that
113
- evaluate_default_scope do
114
- if scope = default_scope
115
- (base_rel ||= relation).merge(scope)
111
+ if default_scope_override
112
+ # The user has defined their own default scope method, so call that
113
+ evaluate_default_scope do
114
+ if scope = default_scope
115
+ (base_rel ||= relation).merge(scope)
116
+ end
116
117
  end
117
- end
118
- elsif default_scopes.any?
119
- base_rel ||= relation
120
- evaluate_default_scope do
121
- default_scopes.inject(base_rel) do |default_scope, scope|
122
- scope = scope.respond_to?(:to_proc) ? scope : scope.method(:call)
123
- default_scope.merge(base_rel.instance_exec(&scope))
118
+ elsif default_scopes.any?
119
+ base_rel ||= relation
120
+ evaluate_default_scope do
121
+ default_scopes.inject(base_rel) do |default_scope, scope|
122
+ scope = scope.respond_to?(:to_proc) ? scope : scope.method(:call)
123
+ default_scope.merge(base_rel.instance_exec(&scope))
124
+ end
124
125
  end
125
126
  end
126
127
  end
127
- end
128
128
 
129
- def ignore_default_scope? # :nodoc:
130
- ScopeRegistry.value_for(:ignore_default_scope, base_class)
131
- end
129
+ def ignore_default_scope?
130
+ ScopeRegistry.value_for(:ignore_default_scope, base_class)
131
+ end
132
132
 
133
- def ignore_default_scope=(ignore) # :nodoc:
134
- ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
135
- end
133
+ def ignore_default_scope=(ignore)
134
+ ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
135
+ end
136
136
 
137
- # The ignore_default_scope flag is used to prevent an infinite recursion
138
- # situation where a default scope references a scope which has a default
139
- # scope which references a scope...
140
- def evaluate_default_scope # :nodoc:
141
- return if ignore_default_scope?
142
-
143
- begin
144
- self.ignore_default_scope = true
145
- yield
146
- ensure
147
- self.ignore_default_scope = false
137
+ # The ignore_default_scope flag is used to prevent an infinite recursion
138
+ # situation where a default scope references a scope which has a default
139
+ # scope which references a scope...
140
+ def evaluate_default_scope
141
+ return if ignore_default_scope?
142
+
143
+ begin
144
+ self.ignore_default_scope = true
145
+ yield
146
+ ensure
147
+ self.ignore_default_scope = false
148
+ end
148
149
  end
149
- end
150
150
  end
151
151
  end
152
152
  end
@@ -1,6 +1,6 @@
1
- require 'active_support/core_ext/array'
2
- require 'active_support/core_ext/hash/except'
3
- require 'active_support/core_ext/kernel/singleton_class'
1
+ require "active_support/core_ext/array"
2
+ require "active_support/core_ext/hash/except"
3
+ require "active_support/core_ext/kernel/singleton_class"
4
4
 
5
5
  module ActiveRecord
6
6
  # = Active Record \Named \Scopes
@@ -54,7 +54,7 @@ module ActiveRecord
54
54
  # Adds a class method for retrieving and querying objects.
55
55
  # The method is intended to return an ActiveRecord::Relation
56
56
  # object, which is composable with other scopes.
57
- # If it returns nil or false, an
57
+ # If it returns +nil+ or +false+, an
58
58
  # {all}[rdoc-ref:Scoping::Named::ClassMethods#all] scope is returned instead.
59
59
  #
60
60
  # A \scope represents a narrowing of a database query, such as
@@ -154,7 +154,7 @@ module ActiveRecord
154
154
  # Article.featured.titles
155
155
  def scope(name, body, &block)
156
156
  unless body.respond_to?(:call)
157
- raise ArgumentError, 'The scope body needs to be callable.'
157
+ raise ArgumentError, "The scope body needs to be callable."
158
158
  end
159
159
 
160
160
  if dangerous_class_method?(name)
@@ -183,14 +183,14 @@ module ActiveRecord
183
183
  end
184
184
  end
185
185
 
186
- protected
186
+ private
187
187
 
188
- def valid_scope_name?(name)
189
- if respond_to?(name, true) && logger
190
- logger.warn "Creating scope :#{name}. " \
191
- "Overwriting existing method #{self.name}.#{name}."
188
+ def valid_scope_name?(name)
189
+ if respond_to?(name, true) && logger
190
+ logger.warn "Creating scope :#{name}. " \
191
+ "Overwriting existing method #{self.name}.#{name}."
192
+ end
192
193
  end
193
- end
194
194
  end
195
195
  end
196
196
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/per_thread_registry'
1
+ require "active_support/per_thread_registry"
2
2
 
3
3
  module ActiveRecord
4
4
  module Scoping
@@ -33,7 +33,7 @@ module ActiveRecord
33
33
  def populate_with_current_scope_attributes # :nodoc:
34
34
  return unless self.class.scope_attributes?
35
35
 
36
- self.class.scope_attributes.each do |att,value|
36
+ self.class.scope_attributes.each do |att, value|
37
37
  send("#{att}=", value) if respond_to?("#{att}=")
38
38
  end
39
39
  end
@@ -95,11 +95,11 @@ module ActiveRecord
95
95
 
96
96
  private
97
97
 
98
- def raise_invalid_scope_type!(scope_type)
99
- if !VALID_SCOPE_TYPES.include?(scope_type)
100
- raise ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry. Scope types must be included in VALID_SCOPE_TYPES"
98
+ def raise_invalid_scope_type!(scope_type)
99
+ if !VALID_SCOPE_TYPES.include?(scope_type)
100
+ raise ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry. Scope types must be included in VALID_SCOPE_TYPES"
101
+ end
101
102
  end
102
- end
103
103
  end
104
104
  end
105
105
  end
@@ -25,9 +25,9 @@ module ActiveRecord
25
25
  # You're encouraged to add a unique index in the database to deal with this even more unlikely scenario.
26
26
  def has_secure_token(attribute = :token)
27
27
  # Load securerandom only when has_secure_token is used.
28
- require 'active_support/core_ext/securerandom'
28
+ require "active_support/core_ext/securerandom"
29
29
  define_method("regenerate_#{attribute}") { update! attribute => self.class.generate_unique_secure_token }
30
- before_create { self.send("#{attribute}=", self.class.generate_unique_secure_token) unless self.send("#{attribute}?")}
30
+ before_create { send("#{attribute}=", self.class.generate_unique_secure_token) unless send("#{attribute}?") }
31
31
  end
32
32
 
33
33
  def generate_unique_secure_token
@@ -1,5 +1,4 @@
1
1
  module ActiveRecord
2
-
3
2
  # Statement cache is used to cache a single statement in order to avoid creating the AST again.
4
3
  # Initializing the cache is done by passing the statement in the create block:
5
4
  #
@@ -8,12 +7,12 @@ module ActiveRecord
8
7
  # end
9
8
  #
10
9
  # The cached statement is executed by using the
11
- # [connection.execute]{rdoc-ref:ConnectionAdapters::DatabaseStatements#execute} method:
10
+ # {connection.execute}[rdoc-ref:ConnectionAdapters::DatabaseStatements#execute] method:
12
11
  #
13
12
  # cache.execute([], Book, Book.connection)
14
13
  #
15
14
  # The relation returned by the block is cached, and for each
16
- # [execute]{rdoc-ref:ConnectionAdapters::DatabaseStatements#execute}
15
+ # {execute}[rdoc-ref:ConnectionAdapters::DatabaseStatements#execute]
17
16
  # call the cached relation gets duped. Database is queried when +to_a+ is called on the relation.
18
17
  #
19
18
  # If you want to cache the statement without the values you can use the +bind+ method of the
@@ -40,28 +39,27 @@ module ActiveRecord
40
39
  end
41
40
 
42
41
  class PartialQuery < Query # :nodoc:
43
- def initialize values
42
+ def initialize(values)
44
43
  @values = values
45
- @indexes = values.each_with_index.find_all { |thing,i|
44
+ @indexes = values.each_with_index.find_all { |thing, i|
46
45
  Arel::Nodes::BindParam === thing
47
46
  }.map(&:last)
48
47
  end
49
48
 
50
49
  def sql_for(binds, connection)
51
50
  val = @values.dup
52
- binds = connection.prepare_binds_for_database(binds)
53
- @indexes.each { |i| val[i] = connection.quote(binds.shift) }
51
+ casted_binds = binds.map(&:value_for_database)
52
+ @indexes.each { |i| val[i] = connection.quote(casted_binds.shift) }
54
53
  val.join
55
54
  end
56
55
  end
57
56
 
58
- def self.query(visitor, ast)
59
- Query.new visitor.accept(ast, Arel::Collectors::SQLString.new).value
57
+ def self.query(sql)
58
+ Query.new(sql)
60
59
  end
61
60
 
62
- def self.partial_query(visitor, ast, collector)
63
- collected = visitor.accept(ast, collector).value
64
- PartialQuery.new collected
61
+ def self.partial_query(values)
62
+ PartialQuery.new(values)
65
63
  end
66
64
 
67
65
  class Params # :nodoc:
@@ -70,7 +68,7 @@ module ActiveRecord
70
68
 
71
69
  class BindMap # :nodoc:
72
70
  def initialize(bound_attributes)
73
- @indexes = []
71
+ @indexes = []
74
72
  @bound_attributes = bound_attributes
75
73
 
76
74
  bound_attributes.each_with_index do |attr, i|
@@ -82,7 +80,7 @@ module ActiveRecord
82
80
 
83
81
  def bind(values)
84
82
  bas = @bound_attributes.dup
85
- @indexes.each_with_index { |offset,i| bas[offset] = bas[offset].with_cast_value(values[i]) }
83
+ @indexes.each_with_index { |offset, i| bas[offset] = bas[offset].with_cast_value(values[i]) }
86
84
  bas
87
85
  end
88
86
  end
@@ -92,7 +90,7 @@ module ActiveRecord
92
90
  def self.create(connection, block = Proc.new)
93
91
  relation = block.call Params.new
94
92
  bind_map = BindMap.new relation.bound_attributes
95
- query_builder = connection.cacheable_query relation.arel
93
+ query_builder = connection.cacheable_query(self, relation.arel)
96
94
  new query_builder, bind_map
97
95
  end
98
96
 
@@ -1,4 +1,4 @@
1
- require 'active_support/core_ext/hash/indifferent_access'
1
+ require "active_support/core_ext/hash/indifferent_access"
2
2
 
3
3
  module ActiveRecord
4
4
  # Store gives you a thin wrapper around serialize for the purpose of storing hashes in a single column.
@@ -78,7 +78,7 @@ module ActiveRecord
78
78
 
79
79
  module ClassMethods
80
80
  def store(store_attribute, options = {})
81
- serialize store_attribute, IndifferentCoder.new(options[:coder])
81
+ serialize store_attribute, IndifferentCoder.new(store_attribute, options[:coder])
82
82
  store_accessor(store_attribute, options[:accessors]) if options.has_key? :accessors
83
83
  end
84
84
 
@@ -114,25 +114,24 @@ module ActiveRecord
114
114
 
115
115
  def stored_attributes
116
116
  parent = superclass.respond_to?(:stored_attributes) ? superclass.stored_attributes : {}
117
- if self.local_stored_attributes
118
- parent.merge!(self.local_stored_attributes) { |k, a, b| a | b }
117
+ if local_stored_attributes
118
+ parent.merge!(local_stored_attributes) { |k, a, b| a | b }
119
119
  end
120
120
  parent
121
121
  end
122
122
  end
123
123
 
124
- protected
125
- def read_store_attribute(store_attribute, key)
124
+ private
125
+ def read_store_attribute(store_attribute, key) # :doc:
126
126
  accessor = store_accessor_for(store_attribute)
127
127
  accessor.read(self, store_attribute, key)
128
128
  end
129
129
 
130
- def write_store_attribute(store_attribute, key, value)
130
+ def write_store_attribute(store_attribute, key, value) # :doc:
131
131
  accessor = store_accessor_for(store_attribute)
132
132
  accessor.write(self, store_attribute, key, value)
133
133
  end
134
134
 
135
- private
136
135
  def store_accessor_for(store_attribute)
137
136
  type_for_attribute(store_attribute.to_s).accessor
138
137
  end
@@ -177,34 +176,34 @@ module ActiveRecord
177
176
  end
178
177
  end
179
178
 
180
- class IndifferentCoder # :nodoc:
181
- def initialize(coder_or_class_name)
182
- @coder =
183
- if coder_or_class_name.respond_to?(:load) && coder_or_class_name.respond_to?(:dump)
184
- coder_or_class_name
185
- else
186
- ActiveRecord::Coders::YAMLColumn.new(coder_or_class_name || Object)
187
- end
188
- end
179
+ class IndifferentCoder # :nodoc:
180
+ def initialize(attr_name, coder_or_class_name)
181
+ @coder =
182
+ if coder_or_class_name.respond_to?(:load) && coder_or_class_name.respond_to?(:dump)
183
+ coder_or_class_name
184
+ else
185
+ ActiveRecord::Coders::YAMLColumn.new(attr_name, coder_or_class_name || Object)
186
+ end
187
+ end
189
188
 
190
- def dump(obj)
191
- @coder.dump self.class.as_indifferent_hash(obj)
192
- end
189
+ def dump(obj)
190
+ @coder.dump self.class.as_indifferent_hash(obj)
191
+ end
193
192
 
194
- def load(yaml)
195
- self.class.as_indifferent_hash(@coder.load(yaml || ''))
196
- end
193
+ def load(yaml)
194
+ self.class.as_indifferent_hash(@coder.load(yaml || ""))
195
+ end
197
196
 
198
- def self.as_indifferent_hash(obj)
199
- case obj
200
- when ActiveSupport::HashWithIndifferentAccess
201
- obj
202
- when Hash
203
- obj.with_indifferent_access
204
- else
205
- ActiveSupport::HashWithIndifferentAccess.new
197
+ def self.as_indifferent_hash(obj)
198
+ case obj
199
+ when ActiveSupport::HashWithIndifferentAccess
200
+ obj
201
+ when Hash
202
+ obj.with_indifferent_access
203
+ else
204
+ ActiveSupport::HashWithIndifferentAccess.new
205
+ end
206
206
  end
207
207
  end
208
- end
209
208
  end
210
209
  end
@@ -30,10 +30,11 @@ module ActiveRecord
30
30
 
31
31
  module ClassMethods
32
32
  def suppress(&block)
33
+ previous_state = SuppressorRegistry.suppressed[name]
33
34
  SuppressorRegistry.suppressed[name] = true
34
35
  yield
35
36
  ensure
36
- SuppressorRegistry.suppressed[name] = false
37
+ SuppressorRegistry.suppressed[name] = previous_state
37
38
  end
38
39
  end
39
40
 
@@ -10,9 +10,7 @@ module ActiveRecord
10
10
  end
11
11
 
12
12
  def resolve_column_aliases(hash)
13
- # This method is a hot spot, so for now, use Hash[] to dup the hash.
14
- # https://bugs.ruby-lang.org/issues/7166
15
- new_hash = Hash[hash]
13
+ new_hash = hash.dup
16
14
  hash.each do |key, _|
17
15
  if (key.is_a?(Symbol)) && klass.attribute_alias?(key)
18
16
  new_hash[klass.attribute_alias(key)] = new_hash.delete(key)
@@ -33,10 +31,14 @@ module ActiveRecord
33
31
  if klass
34
32
  klass.type_for_attribute(column_name.to_s)
35
33
  else
36
- Type::Value.new
34
+ Type.default_value
37
35
  end
38
36
  end
39
37
 
38
+ def has_column?(column_name)
39
+ klass && klass.columns_hash.key?(column_name.to_s)
40
+ end
41
+
40
42
  def associated_with?(association_name)
41
43
  klass && klass._reflect_on_association(association_name)
42
44
  end
@@ -62,8 +64,10 @@ module ActiveRecord
62
64
  association && association.polymorphic?
63
65
  end
64
66
 
67
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
68
+ # Workaround for Ruby 2.2 "private attribute?" warning.
65
69
  protected
66
70
 
67
- attr_reader :klass, :arel_table, :association
71
+ attr_reader :klass, :arel_table, :association
68
72
  end
69
73
  end