activerecord 4.2.11.3 → 5.0.7.2

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 (251) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1638 -1132
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +7 -8
  5. data/examples/performance.rb +2 -3
  6. data/examples/simple.rb +0 -1
  7. data/lib/active_record.rb +7 -2
  8. data/lib/active_record/aggregations.rb +34 -21
  9. data/lib/active_record/association_relation.rb +7 -4
  10. data/lib/active_record/associations.rb +347 -218
  11. data/lib/active_record/associations/alias_tracker.rb +19 -16
  12. data/lib/active_record/associations/association.rb +22 -10
  13. data/lib/active_record/associations/association_scope.rb +75 -104
  14. data/lib/active_record/associations/belongs_to_association.rb +21 -32
  15. data/lib/active_record/associations/builder/association.rb +28 -34
  16. data/lib/active_record/associations/builder/belongs_to.rb +43 -18
  17. data/lib/active_record/associations/builder/collection_association.rb +7 -19
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +16 -11
  19. data/lib/active_record/associations/builder/has_many.rb +4 -4
  20. data/lib/active_record/associations/builder/has_one.rb +11 -6
  21. data/lib/active_record/associations/builder/singular_association.rb +13 -11
  22. data/lib/active_record/associations/collection_association.rb +85 -69
  23. data/lib/active_record/associations/collection_proxy.rb +104 -46
  24. data/lib/active_record/associations/foreign_association.rb +1 -1
  25. data/lib/active_record/associations/has_many_association.rb +21 -78
  26. data/lib/active_record/associations/has_many_through_association.rb +6 -47
  27. data/lib/active_record/associations/has_one_association.rb +12 -5
  28. data/lib/active_record/associations/join_dependency.rb +38 -22
  29. data/lib/active_record/associations/join_dependency/join_association.rb +15 -14
  30. data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
  31. data/lib/active_record/associations/preloader.rb +14 -4
  32. data/lib/active_record/associations/preloader/association.rb +52 -71
  33. data/lib/active_record/associations/preloader/collection_association.rb +0 -7
  34. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  35. data/lib/active_record/associations/preloader/has_one.rb +0 -8
  36. data/lib/active_record/associations/preloader/singular_association.rb +0 -1
  37. data/lib/active_record/associations/preloader/through_association.rb +36 -17
  38. data/lib/active_record/associations/singular_association.rb +13 -1
  39. data/lib/active_record/associations/through_association.rb +12 -4
  40. data/lib/active_record/attribute.rb +69 -19
  41. data/lib/active_record/attribute/user_provided_default.rb +28 -0
  42. data/lib/active_record/attribute_assignment.rb +19 -140
  43. data/lib/active_record/attribute_decorators.rb +6 -5
  44. data/lib/active_record/attribute_methods.rb +69 -44
  45. data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
  46. data/lib/active_record/attribute_methods/dirty.rb +46 -86
  47. data/lib/active_record/attribute_methods/primary_key.rb +16 -3
  48. data/lib/active_record/attribute_methods/query.rb +2 -2
  49. data/lib/active_record/attribute_methods/read.rb +31 -59
  50. data/lib/active_record/attribute_methods/serialization.rb +13 -16
  51. data/lib/active_record/attribute_methods/time_zone_conversion.rb +61 -14
  52. data/lib/active_record/attribute_methods/write.rb +13 -37
  53. data/lib/active_record/attribute_mutation_tracker.rb +70 -0
  54. data/lib/active_record/attribute_set.rb +32 -3
  55. data/lib/active_record/attribute_set/builder.rb +42 -16
  56. data/lib/active_record/attributes.rb +199 -81
  57. data/lib/active_record/autosave_association.rb +54 -17
  58. data/lib/active_record/base.rb +32 -23
  59. data/lib/active_record/callbacks.rb +39 -43
  60. data/lib/active_record/coders/json.rb +1 -1
  61. data/lib/active_record/coders/yaml_column.rb +20 -8
  62. data/lib/active_record/collection_cache_key.rb +50 -0
  63. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +467 -189
  64. data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
  65. data/lib/active_record/connection_adapters/abstract/database_statements.rb +66 -62
  66. data/lib/active_record/connection_adapters/abstract/query_cache.rb +39 -4
  67. data/lib/active_record/connection_adapters/abstract/quoting.rb +86 -13
  68. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  69. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +61 -39
  70. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -188
  71. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +72 -17
  72. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +407 -156
  73. data/lib/active_record/connection_adapters/abstract/transaction.rb +51 -34
  74. data/lib/active_record/connection_adapters/abstract_adapter.rb +177 -71
  75. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +433 -399
  76. data/lib/active_record/connection_adapters/column.rb +28 -43
  77. data/lib/active_record/connection_adapters/connection_specification.rb +15 -27
  78. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
  79. data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
  80. data/lib/active_record/connection_adapters/mysql/database_statements.rb +108 -0
  81. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
  82. data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
  83. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
  84. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
  85. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
  86. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
  87. data/lib/active_record/connection_adapters/mysql2_adapter.rb +25 -166
  88. data/lib/active_record/connection_adapters/postgresql/column.rb +33 -11
  89. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +18 -72
  90. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
  92. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +37 -57
  93. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +3 -3
  94. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -2
  95. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  96. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
  97. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +13 -3
  98. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
  99. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -4
  101. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
  102. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +31 -17
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
  106. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +56 -19
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +250 -154
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -2
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +264 -170
  116. data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
  118. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
  119. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
  120. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  121. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +151 -194
  122. data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
  123. data/lib/active_record/connection_handling.rb +37 -14
  124. data/lib/active_record/core.rb +92 -108
  125. data/lib/active_record/counter_cache.rb +13 -24
  126. data/lib/active_record/dynamic_matchers.rb +1 -20
  127. data/lib/active_record/enum.rb +116 -76
  128. data/lib/active_record/errors.rb +87 -48
  129. data/lib/active_record/explain.rb +20 -9
  130. data/lib/active_record/explain_registry.rb +1 -1
  131. data/lib/active_record/explain_subscriber.rb +1 -1
  132. data/lib/active_record/fixture_set/file.rb +26 -5
  133. data/lib/active_record/fixtures.rb +77 -41
  134. data/lib/active_record/gem_version.rb +4 -4
  135. data/lib/active_record/inheritance.rb +32 -40
  136. data/lib/active_record/integration.rb +17 -14
  137. data/lib/active_record/internal_metadata.rb +56 -0
  138. data/lib/active_record/legacy_yaml_adapter.rb +18 -2
  139. data/lib/active_record/locale/en.yml +3 -2
  140. data/lib/active_record/locking/optimistic.rb +15 -15
  141. data/lib/active_record/locking/pessimistic.rb +1 -1
  142. data/lib/active_record/log_subscriber.rb +48 -24
  143. data/lib/active_record/migration.rb +362 -111
  144. data/lib/active_record/migration/command_recorder.rb +59 -18
  145. data/lib/active_record/migration/compatibility.rb +126 -0
  146. data/lib/active_record/model_schema.rb +270 -73
  147. data/lib/active_record/nested_attributes.rb +58 -29
  148. data/lib/active_record/no_touching.rb +4 -0
  149. data/lib/active_record/null_relation.rb +16 -8
  150. data/lib/active_record/persistence.rb +152 -90
  151. data/lib/active_record/query_cache.rb +18 -23
  152. data/lib/active_record/querying.rb +12 -11
  153. data/lib/active_record/railtie.rb +23 -16
  154. data/lib/active_record/railties/controller_runtime.rb +1 -1
  155. data/lib/active_record/railties/databases.rake +52 -41
  156. data/lib/active_record/readonly_attributes.rb +1 -1
  157. data/lib/active_record/reflection.rb +302 -115
  158. data/lib/active_record/relation.rb +187 -120
  159. data/lib/active_record/relation/batches.rb +141 -36
  160. data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
  161. data/lib/active_record/relation/calculations.rb +92 -117
  162. data/lib/active_record/relation/delegation.rb +8 -20
  163. data/lib/active_record/relation/finder_methods.rb +173 -89
  164. data/lib/active_record/relation/from_clause.rb +32 -0
  165. data/lib/active_record/relation/merger.rb +16 -42
  166. data/lib/active_record/relation/predicate_builder.rb +120 -107
  167. data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
  168. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
  169. data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
  170. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
  171. data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
  172. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
  173. data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
  174. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  175. data/lib/active_record/relation/query_attribute.rb +19 -0
  176. data/lib/active_record/relation/query_methods.rb +308 -244
  177. data/lib/active_record/relation/record_fetch_warning.rb +49 -0
  178. data/lib/active_record/relation/spawn_methods.rb +4 -7
  179. data/lib/active_record/relation/where_clause.rb +174 -0
  180. data/lib/active_record/relation/where_clause_factory.rb +38 -0
  181. data/lib/active_record/result.rb +11 -4
  182. data/lib/active_record/runtime_registry.rb +1 -1
  183. data/lib/active_record/sanitization.rb +105 -66
  184. data/lib/active_record/schema.rb +26 -22
  185. data/lib/active_record/schema_dumper.rb +54 -37
  186. data/lib/active_record/schema_migration.rb +11 -14
  187. data/lib/active_record/scoping.rb +34 -16
  188. data/lib/active_record/scoping/default.rb +28 -10
  189. data/lib/active_record/scoping/named.rb +59 -26
  190. data/lib/active_record/secure_token.rb +38 -0
  191. data/lib/active_record/serialization.rb +3 -5
  192. data/lib/active_record/statement_cache.rb +17 -15
  193. data/lib/active_record/store.rb +8 -3
  194. data/lib/active_record/suppressor.rb +58 -0
  195. data/lib/active_record/table_metadata.rb +69 -0
  196. data/lib/active_record/tasks/database_tasks.rb +66 -49
  197. data/lib/active_record/tasks/mysql_database_tasks.rb +6 -14
  198. data/lib/active_record/tasks/postgresql_database_tasks.rb +12 -3
  199. data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
  200. data/lib/active_record/timestamp.rb +20 -9
  201. data/lib/active_record/touch_later.rb +63 -0
  202. data/lib/active_record/transactions.rb +139 -57
  203. data/lib/active_record/type.rb +66 -17
  204. data/lib/active_record/type/adapter_specific_registry.rb +130 -0
  205. data/lib/active_record/type/date.rb +2 -45
  206. data/lib/active_record/type/date_time.rb +2 -49
  207. data/lib/active_record/type/internal/abstract_json.rb +33 -0
  208. data/lib/active_record/type/internal/timezone.rb +15 -0
  209. data/lib/active_record/type/serialized.rb +15 -14
  210. data/lib/active_record/type/time.rb +10 -16
  211. data/lib/active_record/type/type_map.rb +4 -4
  212. data/lib/active_record/type_caster.rb +7 -0
  213. data/lib/active_record/type_caster/connection.rb +29 -0
  214. data/lib/active_record/type_caster/map.rb +19 -0
  215. data/lib/active_record/validations.rb +33 -32
  216. data/lib/active_record/validations/absence.rb +23 -0
  217. data/lib/active_record/validations/associated.rb +10 -3
  218. data/lib/active_record/validations/length.rb +24 -0
  219. data/lib/active_record/validations/presence.rb +11 -12
  220. data/lib/active_record/validations/uniqueness.rb +33 -33
  221. data/lib/rails/generators/active_record/migration.rb +15 -0
  222. data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -5
  223. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
  224. data/lib/rails/generators/active_record/migration/templates/migration.rb +8 -1
  225. data/lib/rails/generators/active_record/model/model_generator.rb +33 -16
  226. data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
  227. data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
  228. metadata +58 -34
  229. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
  230. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  231. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
  232. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  233. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  234. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  235. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  236. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  237. data/lib/active_record/type/big_integer.rb +0 -13
  238. data/lib/active_record/type/binary.rb +0 -50
  239. data/lib/active_record/type/boolean.rb +0 -31
  240. data/lib/active_record/type/decimal.rb +0 -64
  241. data/lib/active_record/type/decimal_without_scale.rb +0 -11
  242. data/lib/active_record/type/decorator.rb +0 -14
  243. data/lib/active_record/type/float.rb +0 -19
  244. data/lib/active_record/type/integer.rb +0 -59
  245. data/lib/active_record/type/mutable.rb +0 -16
  246. data/lib/active_record/type/numeric.rb +0 -36
  247. data/lib/active_record/type/string.rb +0 -40
  248. data/lib/active_record/type/text.rb +0 -11
  249. data/lib/active_record/type/time_value.rb +0 -38
  250. data/lib/active_record/type/unsigned_integer.rb +0 -15
  251. 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,26 @@ 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
+
55
+ ActiveRecord::InternalMetadata.create_table
56
+ ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment
57
+ end
58
+
59
+ private
60
+ # Returns the migrations paths.
61
+ #
62
+ # ActiveRecord::Schema.new.migrations_paths
63
+ # # => ["db/migrate"] # Rails migration path by default.
64
+ def migrations_paths # :nodoc:
65
+ ActiveRecord::Migrator.migrations_paths
66
+ end
63
67
  end
64
68
  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
@@ -52,10 +50,6 @@ module ActiveRecord
52
50
  def header(stream)
53
51
  define_params = @version ? "version: #{@version}" : ""
54
52
 
55
- if stream.respond_to?(:external_encoding) && stream.external_encoding
56
- stream.puts "# encoding: #{stream.external_encoding.name}"
57
- end
58
-
59
53
  stream.puts <<HEADER
60
54
  # This file is auto-generated from the current state of the database. Instead
61
55
  # of editing this file, please use the migrations feature of Active Record to
@@ -91,7 +85,7 @@ HEADER
91
85
  end
92
86
 
93
87
  def tables(stream)
94
- sorted_tables = @connection.tables.sort
88
+ sorted_tables = @connection.data_sources.sort - @connection.views
95
89
 
96
90
  sorted_tables.each do |table_name|
97
91
  table(table_name, stream) unless ignored?(table_name)
@@ -114,27 +108,36 @@ HEADER
114
108
  pk = @connection.primary_key(table)
115
109
 
116
110
  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})
111
+
112
+ case pk
113
+ when String
114
+ tbl.print ", primary_key: #{pk.inspect}" unless pk == 'id'
115
+ pkcol = columns.detect { |c| c.name == pk }
116
+ pkcolspec = @connection.column_spec_for_primary_key(pkcol)
117
+ if pkcolspec.present?
118
+ pkcolspec.each do |key, value|
119
+ tbl.print ", #{key}: #{value}"
120
+ end
126
121
  end
122
+ when Array
123
+ tbl.print ", primary_key: #{pk.inspect}"
127
124
  else
128
125
  tbl.print ", id: false"
129
126
  end
130
127
  tbl.print ", force: :cascade"
128
+
129
+ table_options = @connection.table_options(table)
130
+ if table_options.present?
131
+ tbl.print ", #{format_options(table_options)}"
132
+ end
133
+
131
134
  tbl.puts " do |t|"
132
135
 
133
136
  # then dump all non-primary key columns
134
137
  column_specs = columns.map do |column|
135
138
  raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
136
139
  next if column.name == pk
137
- @connection.column_spec(column, @types)
140
+ @connection.column_spec(column)
138
141
  end.compact
139
142
 
140
143
  # find all migration keys used in this table
@@ -165,11 +168,11 @@ HEADER
165
168
  tbl.puts
166
169
  end
167
170
 
171
+ indexes_in_create(table, tbl)
172
+
168
173
  tbl.puts " end"
169
174
  tbl.puts
170
175
 
171
- indexes(table, tbl)
172
-
173
176
  tbl.rewind
174
177
  stream.print tbl.read
175
178
  rescue => e
@@ -181,26 +184,12 @@ HEADER
181
184
  stream
182
185
  end
183
186
 
187
+ # Keep it for indexing materialized views
184
188
  def indexes(table, stream)
185
189
  if (indexes = @connection.indexes(table)).any?
186
190
  add_index_statements = indexes.map do |index|
187
- statement_parts = [
188
- "add_index #{remove_prefix_and_suffix(index.table).inspect}",
189
- index.columns.inspect,
190
- "name: #{index.name.inspect}",
191
- ]
192
- statement_parts << 'unique: true' if index.unique
193
-
194
- index_lengths = (index.lengths || []).compact
195
- statement_parts << "length: #{Hash[index.columns.zip(index.lengths)].inspect}" if index_lengths.any?
196
-
197
- index_orders = index.orders || {}
198
- statement_parts << "order: #{index.orders.inspect}" if index_orders.any?
199
- statement_parts << "where: #{index.where.inspect}" if index.where
200
- statement_parts << "using: #{index.using.inspect}" if index.using
201
- statement_parts << "type: #{index.type.inspect}" if index.type
202
-
203
- " #{statement_parts.join(', ')}"
191
+ table_name = remove_prefix_and_suffix(index.table).inspect
192
+ " add_index #{([table_name]+index_parts(index)).join(', ')}"
204
193
  end
205
194
 
206
195
  stream.puts add_index_statements.sort.join("\n")
@@ -208,6 +197,30 @@ HEADER
208
197
  end
209
198
  end
210
199
 
200
+ def indexes_in_create(table, stream)
201
+ if (indexes = @connection.indexes(table)).any?
202
+ index_statements = indexes.map do |index|
203
+ " t.index #{index_parts(index).join(', ')}"
204
+ end
205
+ stream.puts index_statements.sort.join("\n")
206
+ end
207
+ end
208
+
209
+ def index_parts(index)
210
+ index_parts = [
211
+ index.columns.inspect,
212
+ "name: #{index.name.inspect}",
213
+ ]
214
+ index_parts << "unique: true" if index.unique
215
+ index_parts << "length: { #{format_options(index.lengths)} }" if index.lengths.present?
216
+ index_parts << "order: { #{format_options(index.orders)} }" if index.orders.present?
217
+ index_parts << "where: #{index.where.inspect}" if index.where
218
+ index_parts << "using: #{index.using.inspect}" if index.using
219
+ index_parts << "type: #{index.type.inspect}" if index.type
220
+ index_parts << "comment: #{index.comment.inspect}" if index.comment
221
+ index_parts
222
+ end
223
+
211
224
  def foreign_keys(table, stream)
212
225
  if (foreign_keys = @connection.foreign_keys(table)).any?
213
226
  add_foreign_key_statements = foreign_keys.map do |foreign_key|
@@ -238,12 +251,16 @@ HEADER
238
251
  end
239
252
  end
240
253
 
254
+ def format_options(options)
255
+ options.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
256
+ end
257
+
241
258
  def remove_prefix_and_suffix(table)
242
259
  table.gsub(/^(#{@options[:table_name_prefix]})(.+)(#{@options[:table_name_suffix]})$/, "\\2")
243
260
  end
244
261
 
245
262
  def ignored?(table_name)
246
- ['schema_migrations', ignore_tables].flatten.any? do |ignored|
263
+ [ActiveRecord::Base.schema_migrations_table_name, ActiveRecord::Base.internal_metadata_table_name, ignore_tables].flatten.any? do |ignored|
247
264
  ignored === remove_prefix_and_suffix(table_name)
248
265
  end
249
266
  end
@@ -1,40 +1,37 @@
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
- nil
12
+ "version"
10
13
  end
11
14
 
12
15
  def table_name
13
16
  "#{table_name_prefix}#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
14
17
  end
15
18
 
16
- def index_name
17
- "#{table_name_prefix}unique_#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
18
- end
19
-
20
19
  def table_exists?
21
- connection.table_exists?(table_name)
20
+ ActiveSupport::Deprecation.silence { connection.table_exists?(table_name) }
22
21
  end
23
22
 
24
- def create_table(limit=nil)
23
+ def create_table
25
24
  unless table_exists?
26
- version_options = {null: false}
27
- version_options[:limit] = limit if limit
25
+ version_options = connection.internal_string_options_for_primary_key
28
26
 
29
27
  connection.create_table(table_name, id: false) do |t|
30
- t.column :version, :string, version_options
28
+ t.string :version, version_options
31
29
  end
32
- connection.add_index table_name, :version, unique: true, name: index_name
33
30
  end
34
31
  end
35
32
 
36
33
  def drop_table
37
- connection.drop_table table_name if table_exists?
34
+ connection.drop_table table_name, if_exists: true
38
35
  end
39
36
 
40
37
  def normalize_migration_number(number)
@@ -10,16 +10,27 @@ module ActiveRecord
10
10
  end
11
11
 
12
12
  module ClassMethods
13
- def current_scope #:nodoc:
14
- ScopeRegistry.value_for(:current_scope, base_class.to_s)
13
+ def current_scope(skip_inherited_scope = false) # :nodoc:
14
+ ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope)
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, 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
@@ -42,18 +53,18 @@ module ActiveRecord
42
53
  # following code:
43
54
  #
44
55
  # registry = ActiveRecord::Scoping::ScopeRegistry
45
- # registry.set_value_for(:current_scope, "Board", some_new_scope)
56
+ # registry.set_value_for(:current_scope, Board, some_new_scope)
46
57
  #
47
58
  # Now when you run:
48
59
  #
49
- # registry.value_for(:current_scope, "Board")
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,
56
- # "Board", some_new_scope)
67
+ # Board, some_new_scope)
57
68
  class ScopeRegistry # :nodoc:
58
69
  extend ActiveSupport::PerThreadRegistry
59
70
 
@@ -63,16 +74,23 @@ module ActiveRecord
63
74
  @registry = Hash.new { |hash, key| hash[key] = {} }
64
75
  end
65
76
 
66
- # Obtains the value for a given +scope_name+ and +variable_name+.
67
- def value_for(scope_type, variable_name)
77
+ # Obtains the value for a given +scope_type+ and +model+.
78
+ def value_for(scope_type, model, skip_inherited_scope = false)
68
79
  raise_invalid_scope_type!(scope_type)
69
- @registry[scope_type][variable_name]
80
+ return @registry[scope_type][model.name] if skip_inherited_scope
81
+ klass = model
82
+ base = model.base_class
83
+ while klass <= base
84
+ value = @registry[scope_type][klass.name]
85
+ return value if value
86
+ klass = klass.superclass
87
+ end
70
88
  end
71
89
 
72
- # Sets the +value+ for a given +scope_type+ and +variable_name+.
73
- def set_value_for(scope_type, variable_name, value)
90
+ # Sets the +value+ for a given +scope_type+ and +model+.
91
+ def set_value_for(scope_type, model, value)
74
92
  raise_invalid_scope_type!(scope_type)
75
- @registry[scope_type][variable_name] = value
93
+ @registry[scope_type][model.name] = value
76
94
  end
77
95
 
78
96
  private
@@ -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_writer: false, 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,26 +101,37 @@ 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
- evaluate_default_scope { default_scope }
113
+ evaluate_default_scope do
114
+ if scope = default_scope
115
+ (base_rel ||= relation).merge(scope)
116
+ end
117
+ end
102
118
  elsif default_scopes.any?
119
+ base_rel ||= relation
103
120
  evaluate_default_scope do
104
121
  default_scopes.inject(base_rel) do |default_scope, scope|
105
- default_scope.merge(base_rel.scoping { scope.call })
122
+ scope = scope.respond_to?(:to_proc) ? scope : scope.method(:call)
123
+ default_scope.merge(base_rel.instance_exec(&scope))
106
124
  end
107
125
  end
108
126
  end
109
127
  end
110
128
 
111
129
  def ignore_default_scope? # :nodoc:
112
- ScopeRegistry.value_for(:ignore_default_scope, self)
130
+ ScopeRegistry.value_for(:ignore_default_scope, base_class)
113
131
  end
114
132
 
115
133
  def ignore_default_scope=(ignore) # :nodoc:
116
- ScopeRegistry.set_value_for(:ignore_default_scope, self, ignore)
134
+ ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
117
135
  end
118
136
 
119
137
  # The ignore_default_scope flag is used to prevent an infinite recursion