activerecord 4.2.11.3 → 5.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 (229) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1029 -1349
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -7
  5. data/examples/performance.rb +2 -2
  6. data/lib/active_record.rb +7 -3
  7. data/lib/active_record/aggregations.rb +35 -25
  8. data/lib/active_record/association_relation.rb +2 -2
  9. data/lib/active_record/associations.rb +305 -204
  10. data/lib/active_record/associations/alias_tracker.rb +19 -16
  11. data/lib/active_record/associations/association.rb +10 -8
  12. data/lib/active_record/associations/association_scope.rb +73 -102
  13. data/lib/active_record/associations/belongs_to_association.rb +20 -32
  14. data/lib/active_record/associations/builder/association.rb +28 -34
  15. data/lib/active_record/associations/builder/belongs_to.rb +41 -18
  16. data/lib/active_record/associations/builder/collection_association.rb +8 -24
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +11 -11
  18. data/lib/active_record/associations/builder/has_many.rb +4 -4
  19. data/lib/active_record/associations/builder/has_one.rb +10 -5
  20. data/lib/active_record/associations/builder/singular_association.rb +2 -9
  21. data/lib/active_record/associations/collection_association.rb +40 -43
  22. data/lib/active_record/associations/collection_proxy.rb +55 -29
  23. data/lib/active_record/associations/foreign_association.rb +1 -1
  24. data/lib/active_record/associations/has_many_association.rb +20 -71
  25. data/lib/active_record/associations/has_many_through_association.rb +8 -52
  26. data/lib/active_record/associations/has_one_association.rb +12 -5
  27. data/lib/active_record/associations/join_dependency.rb +28 -18
  28. data/lib/active_record/associations/join_dependency/join_association.rb +13 -12
  29. data/lib/active_record/associations/preloader.rb +13 -4
  30. data/lib/active_record/associations/preloader/association.rb +45 -51
  31. data/lib/active_record/associations/preloader/collection_association.rb +0 -6
  32. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  33. data/lib/active_record/associations/preloader/has_one.rb +0 -8
  34. data/lib/active_record/associations/preloader/through_association.rb +5 -4
  35. data/lib/active_record/associations/singular_association.rb +6 -0
  36. data/lib/active_record/associations/through_association.rb +11 -3
  37. data/lib/active_record/attribute.rb +61 -17
  38. data/lib/active_record/attribute/user_provided_default.rb +23 -0
  39. data/lib/active_record/attribute_assignment.rb +27 -140
  40. data/lib/active_record/attribute_decorators.rb +6 -5
  41. data/lib/active_record/attribute_methods.rb +79 -26
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
  43. data/lib/active_record/attribute_methods/dirty.rb +46 -86
  44. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  45. data/lib/active_record/attribute_methods/query.rb +2 -2
  46. data/lib/active_record/attribute_methods/read.rb +26 -42
  47. data/lib/active_record/attribute_methods/serialization.rb +13 -16
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +42 -9
  49. data/lib/active_record/attribute_methods/write.rb +13 -24
  50. data/lib/active_record/attribute_mutation_tracker.rb +70 -0
  51. data/lib/active_record/attribute_set.rb +30 -3
  52. data/lib/active_record/attribute_set/builder.rb +6 -4
  53. data/lib/active_record/attributes.rb +194 -81
  54. data/lib/active_record/autosave_association.rb +33 -15
  55. data/lib/active_record/base.rb +30 -18
  56. data/lib/active_record/callbacks.rb +36 -40
  57. data/lib/active_record/coders/yaml_column.rb +20 -8
  58. data/lib/active_record/collection_cache_key.rb +31 -0
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +431 -122
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +40 -22
  62. data/lib/active_record/connection_adapters/abstract/quoting.rb +62 -8
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +46 -38
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +229 -185
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +52 -13
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +275 -115
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +32 -33
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +83 -32
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +384 -221
  70. data/lib/active_record/connection_adapters/column.rb +27 -41
  71. data/lib/active_record/connection_adapters/connection_specification.rb +2 -21
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
  73. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +57 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +69 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +59 -0
  76. data/lib/active_record/connection_adapters/mysql2_adapter.rb +22 -101
  77. data/lib/active_record/connection_adapters/postgresql/column.rb +6 -10
  78. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +3 -3
  79. data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
  80. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +23 -57
  81. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
  85. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +3 -3
  86. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
  87. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +23 -16
  92. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
  93. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
  96. data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -11
  97. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
  98. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
  99. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +54 -0
  100. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +174 -128
  101. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
  102. data/lib/active_record/connection_adapters/postgresql_adapter.rb +184 -112
  103. data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
  104. data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
  105. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +15 -0
  106. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +134 -110
  107. data/lib/active_record/connection_adapters/statement_pool.rb +28 -11
  108. data/lib/active_record/connection_handling.rb +5 -5
  109. data/lib/active_record/core.rb +72 -104
  110. data/lib/active_record/counter_cache.rb +9 -20
  111. data/lib/active_record/dynamic_matchers.rb +1 -20
  112. data/lib/active_record/enum.rb +110 -76
  113. data/lib/active_record/errors.rb +72 -47
  114. data/lib/active_record/explain_registry.rb +1 -1
  115. data/lib/active_record/explain_subscriber.rb +1 -1
  116. data/lib/active_record/fixture_set/file.rb +19 -4
  117. data/lib/active_record/fixtures.rb +76 -40
  118. data/lib/active_record/gem_version.rb +4 -4
  119. data/lib/active_record/inheritance.rb +27 -40
  120. data/lib/active_record/integration.rb +4 -4
  121. data/lib/active_record/legacy_yaml_adapter.rb +18 -2
  122. data/lib/active_record/locale/en.yml +3 -2
  123. data/lib/active_record/locking/optimistic.rb +10 -14
  124. data/lib/active_record/locking/pessimistic.rb +1 -1
  125. data/lib/active_record/log_subscriber.rb +40 -22
  126. data/lib/active_record/migration.rb +304 -133
  127. data/lib/active_record/migration/command_recorder.rb +59 -18
  128. data/lib/active_record/migration/compatibility.rb +90 -0
  129. data/lib/active_record/model_schema.rb +92 -40
  130. data/lib/active_record/nested_attributes.rb +45 -34
  131. data/lib/active_record/null_relation.rb +15 -7
  132. data/lib/active_record/persistence.rb +112 -72
  133. data/lib/active_record/querying.rb +6 -5
  134. data/lib/active_record/railtie.rb +20 -13
  135. data/lib/active_record/railties/controller_runtime.rb +1 -1
  136. data/lib/active_record/railties/databases.rake +47 -38
  137. data/lib/active_record/readonly_attributes.rb +1 -1
  138. data/lib/active_record/reflection.rb +182 -57
  139. data/lib/active_record/relation.rb +152 -100
  140. data/lib/active_record/relation/batches.rb +133 -33
  141. data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
  142. data/lib/active_record/relation/calculations.rb +80 -101
  143. data/lib/active_record/relation/delegation.rb +6 -19
  144. data/lib/active_record/relation/finder_methods.rb +58 -46
  145. data/lib/active_record/relation/from_clause.rb +32 -0
  146. data/lib/active_record/relation/merger.rb +13 -42
  147. data/lib/active_record/relation/predicate_builder.rb +99 -105
  148. data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
  149. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +78 -0
  150. data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
  151. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
  152. data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
  153. data/lib/active_record/relation/predicate_builder/range_handler.rb +17 -0
  154. data/lib/active_record/relation/query_attribute.rb +19 -0
  155. data/lib/active_record/relation/query_methods.rb +274 -238
  156. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  157. data/lib/active_record/relation/spawn_methods.rb +3 -6
  158. data/lib/active_record/relation/where_clause.rb +173 -0
  159. data/lib/active_record/relation/where_clause_factory.rb +37 -0
  160. data/lib/active_record/result.rb +4 -3
  161. data/lib/active_record/runtime_registry.rb +1 -1
  162. data/lib/active_record/sanitization.rb +94 -65
  163. data/lib/active_record/schema.rb +23 -22
  164. data/lib/active_record/schema_dumper.rb +33 -22
  165. data/lib/active_record/schema_migration.rb +10 -4
  166. data/lib/active_record/scoping.rb +17 -6
  167. data/lib/active_record/scoping/default.rb +19 -6
  168. data/lib/active_record/scoping/named.rb +39 -28
  169. data/lib/active_record/secure_token.rb +38 -0
  170. data/lib/active_record/serialization.rb +2 -4
  171. data/lib/active_record/statement_cache.rb +15 -13
  172. data/lib/active_record/store.rb +8 -3
  173. data/lib/active_record/suppressor.rb +54 -0
  174. data/lib/active_record/table_metadata.rb +64 -0
  175. data/lib/active_record/tasks/database_tasks.rb +30 -40
  176. data/lib/active_record/tasks/mysql_database_tasks.rb +7 -15
  177. data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -2
  178. data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
  179. data/lib/active_record/timestamp.rb +16 -9
  180. data/lib/active_record/touch_later.rb +58 -0
  181. data/lib/active_record/transactions.rb +138 -56
  182. data/lib/active_record/type.rb +66 -17
  183. data/lib/active_record/type/adapter_specific_registry.rb +130 -0
  184. data/lib/active_record/type/date.rb +2 -45
  185. data/lib/active_record/type/date_time.rb +2 -49
  186. data/lib/active_record/type/internal/abstract_json.rb +33 -0
  187. data/lib/active_record/type/internal/timezone.rb +15 -0
  188. data/lib/active_record/type/serialized.rb +9 -14
  189. data/lib/active_record/type/time.rb +3 -21
  190. data/lib/active_record/type/type_map.rb +4 -4
  191. data/lib/active_record/type_caster.rb +7 -0
  192. data/lib/active_record/type_caster/connection.rb +29 -0
  193. data/lib/active_record/type_caster/map.rb +19 -0
  194. data/lib/active_record/validations.rb +33 -32
  195. data/lib/active_record/validations/absence.rb +24 -0
  196. data/lib/active_record/validations/associated.rb +10 -3
  197. data/lib/active_record/validations/length.rb +36 -0
  198. data/lib/active_record/validations/presence.rb +12 -12
  199. data/lib/active_record/validations/uniqueness.rb +24 -21
  200. data/lib/rails/generators/active_record/migration.rb +7 -0
  201. data/lib/rails/generators/active_record/migration/migration_generator.rb +7 -4
  202. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
  203. data/lib/rails/generators/active_record/migration/templates/migration.rb +4 -1
  204. data/lib/rails/generators/active_record/model/model_generator.rb +21 -15
  205. data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
  206. metadata +50 -35
  207. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
  208. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  209. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
  210. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  211. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  212. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  213. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  214. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  215. data/lib/active_record/type/big_integer.rb +0 -13
  216. data/lib/active_record/type/binary.rb +0 -50
  217. data/lib/active_record/type/boolean.rb +0 -31
  218. data/lib/active_record/type/decimal.rb +0 -64
  219. data/lib/active_record/type/decimal_without_scale.rb +0 -11
  220. data/lib/active_record/type/decorator.rb +0 -14
  221. data/lib/active_record/type/float.rb +0 -19
  222. data/lib/active_record/type/integer.rb +0 -59
  223. data/lib/active_record/type/mutable.rb +0 -16
  224. data/lib/active_record/type/numeric.rb +0 -36
  225. data/lib/active_record/type/string.rb +0 -40
  226. data/lib/active_record/type/text.rb +0 -11
  227. data/lib/active_record/type/time_value.rb +0 -38
  228. data/lib/active_record/type/unsigned_integer.rb +0 -15
  229. data/lib/active_record/type/value.rb +0 -110
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
- # = Active Record Schema
2
+ # = Active Record \Schema
3
3
  #
4
4
  # Allows programmers to programmatically define a schema in a portable
5
5
  # DSL. This means you can define tables, indexes, etc. without using SQL
@@ -27,29 +27,12 @@ module ActiveRecord
27
27
  #
28
28
  # ActiveRecord::Schema is only supported by database adapters that also
29
29
  # support migrations, the two features being very similar.
30
- class Schema < Migration
31
-
32
- # Returns the migrations paths.
33
- #
34
- # ActiveRecord::Schema.new.migrations_paths
35
- # # => ["db/migrate"] # Rails migration path by default.
36
- def migrations_paths
37
- ActiveRecord::Migrator.migrations_paths
38
- end
39
-
40
- def define(info, &block) # :nodoc:
41
- instance_eval(&block)
42
-
43
- unless info[:version].blank?
44
- initialize_schema_migrations_table
45
- connection.assume_migrated_upto_version(info[:version], migrations_paths)
46
- end
47
- end
48
-
30
+ class Schema < Migration::Current
49
31
  # Eval the given block. All methods available to the current connection
50
32
  # adapter are available within the block, so you can easily use the
51
- # database definition DSL to build up your schema (+create_table+,
52
- # +add_index+, etc.).
33
+ # database definition DSL to build up your schema (
34
+ # {create_table}[rdoc-ref:ConnectionAdapters::SchemaStatements#create_table],
35
+ # {add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index], etc.).
53
36
  #
54
37
  # The +info+ hash is optional, and if given is used to define metadata
55
38
  # about the current schema (currently, only the schema's version):
@@ -60,5 +43,23 @@ module ActiveRecord
60
43
  def self.define(info={}, &block)
61
44
  new.define(info, &block)
62
45
  end
46
+
47
+ def define(info, &block) # :nodoc:
48
+ instance_eval(&block)
49
+
50
+ if info[:version].present?
51
+ initialize_schema_migrations_table
52
+ connection.assume_migrated_upto_version(info[:version], migrations_paths)
53
+ end
54
+ end
55
+
56
+ private
57
+ # Returns the migrations paths.
58
+ #
59
+ # ActiveRecord::Schema.new.migrations_paths
60
+ # # => ["db/migrate"] # Rails migration path by default.
61
+ def migrations_paths # :nodoc:
62
+ ActiveRecord::Migrator.migrations_paths
63
+ end
63
64
  end
64
65
  end
@@ -1,5 +1,4 @@
1
1
  require 'stringio'
2
- require 'active_support/core_ext/big_decimal'
3
2
 
4
3
  module ActiveRecord
5
4
  # = Active Record Schema Dumper
@@ -44,7 +43,6 @@ module ActiveRecord
44
43
 
45
44
  def initialize(connection, options = {})
46
45
  @connection = connection
47
- @types = @connection.native_database_types
48
46
  @version = Migrator::current_version rescue nil
49
47
  @options = options
50
48
  end
@@ -91,7 +89,7 @@ HEADER
91
89
  end
92
90
 
93
91
  def tables(stream)
94
- sorted_tables = @connection.tables.sort
92
+ sorted_tables = @connection.data_sources.sort - @connection.views
95
93
 
96
94
  sorted_tables.each do |table_name|
97
95
  table(table_name, stream) unless ignored?(table_name)
@@ -106,35 +104,50 @@ HEADER
106
104
  end
107
105
 
108
106
  def table(table, stream)
109
- columns = @connection.columns(table)
107
+ columns = @connection.columns(table).map do |column|
108
+ column.instance_variable_set(:@table_name, table)
109
+ column
110
+ end
110
111
  begin
111
112
  tbl = StringIO.new
112
113
 
113
114
  # first dump primary key column
114
- pk = @connection.primary_key(table)
115
+ if @connection.respond_to?(:primary_keys)
116
+ pk = @connection.primary_keys(table)
117
+ pk = pk.first unless pk.size > 1
118
+ else
119
+ pk = @connection.primary_key(table)
120
+ end
115
121
 
116
122
  tbl.print " create_table #{remove_prefix_and_suffix(table).inspect}"
117
- pkcol = columns.detect { |c| c.name == pk }
118
- if pkcol
119
- if pk != 'id'
120
- tbl.print %Q(, primary_key: "#{pk}")
121
- elsif pkcol.sql_type == 'bigint'
122
- tbl.print ", id: :bigserial"
123
- elsif pkcol.sql_type == 'uuid'
124
- tbl.print ", id: :uuid"
125
- tbl.print %Q(, default: #{pkcol.default_function.inspect})
123
+
124
+ case pk
125
+ when String
126
+ tbl.print ", primary_key: #{pk.inspect}" unless pk == 'id'
127
+ pkcol = columns.detect { |c| c.name == pk }
128
+ pkcolspec = @connection.column_spec_for_primary_key(pkcol)
129
+ if pkcolspec
130
+ pkcolspec.each do |key, value|
131
+ tbl.print ", #{key}: #{value}"
132
+ end
126
133
  end
134
+ when Array
135
+ tbl.print ", primary_key: #{pk.inspect}"
127
136
  else
128
137
  tbl.print ", id: false"
129
138
  end
130
139
  tbl.print ", force: :cascade"
140
+
141
+ table_options = @connection.table_options(table)
142
+ tbl.print ", options: #{table_options.inspect}" unless table_options.blank?
143
+
131
144
  tbl.puts " do |t|"
132
145
 
133
146
  # then dump all non-primary key columns
134
147
  column_specs = columns.map do |column|
135
148
  raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
136
149
  next if column.name == pk
137
- @connection.column_spec(column, @types)
150
+ @connection.column_spec(column)
138
151
  end.compact
139
152
 
140
153
  # find all migration keys used in this table
@@ -165,11 +178,11 @@ HEADER
165
178
  tbl.puts
166
179
  end
167
180
 
181
+ indexes(table, tbl)
182
+
168
183
  tbl.puts " end"
169
184
  tbl.puts
170
185
 
171
- indexes(table, tbl)
172
-
173
186
  tbl.rewind
174
187
  stream.print tbl.read
175
188
  rescue => e
@@ -185,8 +198,7 @@ HEADER
185
198
  if (indexes = @connection.indexes(table)).any?
186
199
  add_index_statements = indexes.map do |index|
187
200
  statement_parts = [
188
- "add_index #{remove_prefix_and_suffix(index.table).inspect}",
189
- index.columns.inspect,
201
+ "t.index #{index.columns.inspect}",
190
202
  "name: #{index.name.inspect}",
191
203
  ]
192
204
  statement_parts << 'unique: true' if index.unique
@@ -200,11 +212,10 @@ HEADER
200
212
  statement_parts << "using: #{index.using.inspect}" if index.using
201
213
  statement_parts << "type: #{index.type.inspect}" if index.type
202
214
 
203
- " #{statement_parts.join(', ')}"
215
+ " #{statement_parts.join(', ')}"
204
216
  end
205
217
 
206
218
  stream.puts add_index_statements.sort.join("\n")
207
- stream.puts
208
219
  end
209
220
  end
210
221
 
@@ -243,7 +254,7 @@ HEADER
243
254
  end
244
255
 
245
256
  def ignored?(table_name)
246
- ['schema_migrations', ignore_tables].flatten.any? do |ignored|
257
+ [ActiveRecord::Base.schema_migrations_table_name, ignore_tables].flatten.any? do |ignored|
247
258
  ignored === remove_prefix_and_suffix(table_name)
248
259
  end
249
260
  end
@@ -1,9 +1,12 @@
1
1
  require 'active_record/scoping/default'
2
2
  require 'active_record/scoping/named'
3
- require 'active_record/base'
4
3
 
5
4
  module ActiveRecord
6
- class SchemaMigration < ActiveRecord::Base
5
+ # This class is used to create a table that keeps track of which migrations
6
+ # have been applied to a given database. When a migration is run, its schema
7
+ # number is inserted in to the `SchemaMigration.table_name` so it doesn't need
8
+ # to be executed the next time.
9
+ class SchemaMigration < ActiveRecord::Base # :nodoc:
7
10
  class << self
8
11
  def primary_key
9
12
  nil
@@ -18,7 +21,7 @@ module ActiveRecord
18
21
  end
19
22
 
20
23
  def table_exists?
21
- connection.table_exists?(table_name)
24
+ ActiveSupport::Deprecation.silence { connection.table_exists?(table_name) }
22
25
  end
23
26
 
24
27
  def create_table(limit=nil)
@@ -34,7 +37,10 @@ module ActiveRecord
34
37
  end
35
38
 
36
39
  def drop_table
37
- connection.drop_table table_name if table_exists?
40
+ if table_exists?
41
+ connection.remove_index table_name, name: index_name
42
+ connection.drop_table(table_name)
43
+ end
38
44
  end
39
45
 
40
46
  def normalize_migration_number(number)
@@ -11,15 +11,26 @@ module ActiveRecord
11
11
 
12
12
  module ClassMethods
13
13
  def current_scope #:nodoc:
14
- ScopeRegistry.value_for(:current_scope, base_class.to_s)
14
+ ScopeRegistry.value_for(:current_scope, self.to_s)
15
15
  end
16
16
 
17
17
  def current_scope=(scope) #:nodoc:
18
- ScopeRegistry.set_value_for(:current_scope, base_class.to_s, scope)
18
+ ScopeRegistry.set_value_for(:current_scope, self.to_s, scope)
19
+ end
20
+
21
+ # Collects attributes from scopes that should be applied when creating
22
+ # an AR instance for the particular class this is called on.
23
+ def scope_attributes # :nodoc:
24
+ all.scope_for_create
25
+ end
26
+
27
+ # Are there attributes associated with this scope?
28
+ def scope_attributes? # :nodoc:
29
+ current_scope
19
30
  end
20
31
  end
21
32
 
22
- def populate_with_current_scope_attributes
33
+ def populate_with_current_scope_attributes # :nodoc:
23
34
  return unless self.class.scope_attributes?
24
35
 
25
36
  self.class.scope_attributes.each do |att,value|
@@ -27,7 +38,7 @@ module ActiveRecord
27
38
  end
28
39
  end
29
40
 
30
- def initialize_internals_callback
41
+ def initialize_internals_callback # :nodoc:
31
42
  super
32
43
  populate_with_current_scope_attributes
33
44
  end
@@ -48,8 +59,8 @@ module ActiveRecord
48
59
  #
49
60
  # registry.value_for(:current_scope, "Board")
50
61
  #
51
- # You will obtain whatever was defined in +some_new_scope+. The +value_for+
52
- # and +set_value_for+ methods are delegated to the current +ScopeRegistry+
62
+ # You will obtain whatever was defined in +some_new_scope+. The #value_for
63
+ # and #set_value_for methods are delegated to the current ScopeRegistry
53
64
  # object, so the above example code can also be called as:
54
65
  #
55
66
  # ActiveRecord::Scoping::ScopeRegistry.set_value_for(:current_scope,
@@ -6,8 +6,10 @@ module ActiveRecord
6
6
  included do
7
7
  # Stores the default scope for the class.
8
8
  class_attribute :default_scopes, instance_writer: false, instance_predicate: false
9
+ class_attribute :default_scope_override, instance_predicate: false
9
10
 
10
11
  self.default_scopes = []
12
+ self.default_scope_override = nil
11
13
  end
12
14
 
13
15
  module ClassMethods
@@ -15,7 +17,7 @@ module ActiveRecord
15
17
  #
16
18
  # class Post < ActiveRecord::Base
17
19
  # def self.default_scope
18
- # where published: true
20
+ # where(published: true)
19
21
  # end
20
22
  # end
21
23
  #
@@ -33,6 +35,11 @@ module ActiveRecord
33
35
  block_given? ? relation.scoping { yield } : relation
34
36
  end
35
37
 
38
+ # Are there attributes associated with this scope?
39
+ def scope_attributes? # :nodoc:
40
+ super || default_scopes.any? || respond_to?(:default_scope)
41
+ end
42
+
36
43
  def before_remove_const #:nodoc:
37
44
  self.current_scope = nil
38
45
  end
@@ -48,7 +55,7 @@ module ActiveRecord
48
55
  #
49
56
  # Article.all # => SELECT * FROM articles WHERE published = true
50
57
  #
51
- # The +default_scope+ is also applied while creating/building a record.
58
+ # The #default_scope is also applied while creating/building a record.
52
59
  # It is not applied while updating a record.
53
60
  #
54
61
  # Article.new.published # => true
@@ -58,7 +65,7 @@ module ActiveRecord
58
65
  # +default_scope+ macro, and it will be called when building the
59
66
  # default scope.)
60
67
  #
61
- # If you use multiple +default_scope+ declarations in your model then
68
+ # If you use multiple #default_scope declarations in your model then
62
69
  # they will be merged together:
63
70
  #
64
71
  # class Article < ActiveRecord::Base
@@ -69,7 +76,7 @@ module ActiveRecord
69
76
  # Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
70
77
  #
71
78
  # This is also the case with inheritance and module includes where the
72
- # parent or module defines a +default_scope+ and the child or including
79
+ # parent or module defines a #default_scope and the child or including
73
80
  # class defines a second one.
74
81
  #
75
82
  # If you need to do more complex things with a default scope, you can
@@ -94,12 +101,18 @@ module ActiveRecord
94
101
  self.default_scopes += [scope]
95
102
  end
96
103
 
97
- def build_default_scope(base_rel = relation) # :nodoc:
104
+ def build_default_scope(base_rel = nil) # :nodoc:
98
105
  return if abstract_class?
99
- if !Base.is_a?(method(:default_scope).owner)
106
+
107
+ if self.default_scope_override.nil?
108
+ self.default_scope_override = !Base.is_a?(method(:default_scope).owner)
109
+ end
110
+
111
+ if self.default_scope_override
100
112
  # The user has defined their own default scope method, so call that
101
113
  evaluate_default_scope { default_scope }
102
114
  elsif default_scopes.any?
115
+ base_rel ||= relation
103
116
  evaluate_default_scope do
104
117
  default_scopes.inject(base_rel) do |default_scope, scope|
105
118
  default_scope.merge(base_rel.scoping { scope.call })
@@ -9,7 +9,7 @@ module ActiveRecord
9
9
  extend ActiveSupport::Concern
10
10
 
11
11
  module ClassMethods
12
- # Returns an <tt>ActiveRecord::Relation</tt> scope object.
12
+ # Returns an ActiveRecord::Relation scope object.
13
13
  #
14
14
  # posts = Post.all
15
15
  # posts.size # Fires "select count(*) from posts" and returns the count
@@ -20,7 +20,7 @@ module ActiveRecord
20
20
  # fruits = fruits.limit(10) if limited?
21
21
  #
22
22
  # You can define a scope that applies to all finders using
23
- # <tt>ActiveRecord::Base.default_scope</tt>.
23
+ # {default_scope}[rdoc-ref:Scoping::Default::ClassMethods#default_scope].
24
24
  def all
25
25
  if current_scope
26
26
  current_scope.clone
@@ -30,22 +30,22 @@ module ActiveRecord
30
30
  end
31
31
 
32
32
  def default_scoped # :nodoc:
33
- relation.merge(build_default_scope)
34
- end
35
-
36
- # Collects attributes from scopes that should be applied when creating
37
- # an AR instance for the particular class this is called on.
38
- def scope_attributes # :nodoc:
39
- all.scope_for_create
40
- end
33
+ scope = build_default_scope
41
34
 
42
- # Are there default attributes associated with this scope?
43
- def scope_attributes? # :nodoc:
44
- current_scope || default_scopes.any?
35
+ if scope
36
+ relation.spawn.merge!(scope)
37
+ else
38
+ relation
39
+ end
45
40
  end
46
41
 
47
- # Adds a class method for retrieving and querying objects. A \scope
48
- # represents a narrowing of a database query, such as
42
+ # Adds a class method for retrieving and querying objects.
43
+ # The method is intended to return an ActiveRecord::Relation
44
+ # object, which is composable with other scopes.
45
+ # If it returns nil or false, an
46
+ # {all}[rdoc-ref:Scoping::Named::ClassMethods#all] scope is returned instead.
47
+ #
48
+ # A \scope represents a narrowing of a database query, such as
49
49
  # <tt>where(color: :red).select('shirts.*').includes(:washing_instructions)</tt>.
50
50
  #
51
51
  # class Shirt < ActiveRecord::Base
@@ -53,12 +53,12 @@ module ActiveRecord
53
53
  # scope :dry_clean_only, -> { joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true) }
54
54
  # end
55
55
  #
56
- # The above calls to +scope+ define class methods <tt>Shirt.red</tt> and
56
+ # The above calls to #scope define class methods <tt>Shirt.red</tt> and
57
57
  # <tt>Shirt.dry_clean_only</tt>. <tt>Shirt.red</tt>, in effect,
58
58
  # represents the query <tt>Shirt.where(color: 'red')</tt>.
59
59
  #
60
60
  # You should always pass a callable object to the scopes defined
61
- # with +scope+. This ensures that the scope is re-evaluated each
61
+ # with #scope. This ensures that the scope is re-evaluated each
62
62
  # time it is called.
63
63
  #
64
64
  # Note that this is simply 'syntactic sugar' for defining an actual
@@ -71,14 +71,15 @@ module ActiveRecord
71
71
  # end
72
72
  #
73
73
  # Unlike <tt>Shirt.find(...)</tt>, however, the object returned by
74
- # <tt>Shirt.red</tt> is not an Array; it resembles the association object
75
- # constructed by a +has_many+ declaration. For instance, you can invoke
76
- # <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>,
74
+ # <tt>Shirt.red</tt> is not an Array but an ActiveRecord::Relation,
75
+ # which is composable with other scopes; it resembles the association object
76
+ # constructed by a {has_many}[rdoc-ref:Associations::ClassMethods#has_many]
77
+ # declaration. For instance, you can invoke <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>,
77
78
  # <tt>Shirt.red.where(size: 'small')</tt>. Also, just as with the
78
79
  # association objects, named \scopes act like an Array, implementing
79
80
  # Enumerable; <tt>Shirt.red.each(&block)</tt>, <tt>Shirt.red.first</tt>,
80
81
  # and <tt>Shirt.red.inject(memo, &block)</tt> all behave as if
81
- # <tt>Shirt.red</tt> really was an Array.
82
+ # <tt>Shirt.red</tt> really was an array.
82
83
  #
83
84
  # These named \scopes are composable. For instance,
84
85
  # <tt>Shirt.red.dry_clean_only</tt> will produce all shirts that are
@@ -89,7 +90,8 @@ module ActiveRecord
89
90
  #
90
91
  # All scopes are available as class methods on the ActiveRecord::Base
91
92
  # descendant upon which the \scopes were defined. But they are also
92
- # available to +has_many+ associations. If,
93
+ # available to {has_many}[rdoc-ref:Associations::ClassMethods#has_many]
94
+ # associations. If,
93
95
  #
94
96
  # class Person < ActiveRecord::Base
95
97
  # has_many :shirts
@@ -98,8 +100,8 @@ module ActiveRecord
98
100
  # then <tt>elton.shirts.red.dry_clean_only</tt> will return all of
99
101
  # Elton's red, dry clean only shirts.
100
102
  #
101
- # \Named scopes can also have extensions, just as with +has_many+
102
- # declarations:
103
+ # \Named scopes can also have extensions, just as with
104
+ # {has_many}[rdoc-ref:Associations::ClassMethods#has_many] declarations:
103
105
  #
104
106
  # class Shirt < ActiveRecord::Base
105
107
  # scope :red, -> { where(color: 'red') } do
@@ -151,11 +153,20 @@ module ActiveRecord
151
153
 
152
154
  extension = Module.new(&block) if block
153
155
 
154
- singleton_class.send(:define_method, name) do |*args|
155
- scope = all.scoping { body.call(*args) }
156
- scope = scope.extending(extension) if extension
156
+ if body.respond_to?(:to_proc)
157
+ singleton_class.send(:define_method, name) do |*args|
158
+ scope = all.scoping { instance_exec(*args, &body) }
159
+ scope = scope.extending(extension) if extension
160
+
161
+ scope || all
162
+ end
163
+ else
164
+ singleton_class.send(:define_method, name) do |*args|
165
+ scope = all.scoping { body.call(*args) }
166
+ scope = scope.extending(extension) if extension
157
167
 
158
- scope || all
168
+ scope || all
169
+ end
159
170
  end
160
171
  end
161
172
  end