activerecord 4.2.11.1 → 5.0.0

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