activerecord 5.1.7 → 5.2.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +221 -900
- data/README.rdoc +3 -3
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record.rb +10 -3
- data/lib/active_record/aggregations.rb +2 -0
- data/lib/active_record/association_relation.rb +2 -0
- data/lib/active_record/associations.rb +13 -42
- data/lib/active_record/associations/alias_tracker.rb +17 -17
- data/lib/active_record/associations/association.rb +11 -22
- data/lib/active_record/associations/association_scope.rb +32 -44
- data/lib/active_record/associations/belongs_to_association.rb +6 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -1
- data/lib/active_record/associations/builder/association.rb +2 -5
- data/lib/active_record/associations/builder/belongs_to.rb +7 -12
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +2 -0
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +41 -33
- data/lib/active_record/associations/collection_proxy.rb +11 -14
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +4 -2
- data/lib/active_record/associations/has_many_through_association.rb +4 -2
- data/lib/active_record/associations/has_one_association.rb +3 -1
- data/lib/active_record/associations/has_one_through_association.rb +3 -1
- data/lib/active_record/associations/join_dependency.rb +22 -40
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/preloader/association.rb +42 -58
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +3 -1
- data/lib/active_record/attribute_assignment.rb +2 -0
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods.rb +47 -7
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +25 -214
- data/lib/active_record/attribute_methods/primary_key.rb +7 -6
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +8 -2
- data/lib/active_record/attribute_methods/serialization.rb +23 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
- data/lib/active_record/attribute_methods/write.rb +21 -9
- data/lib/active_record/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +5 -11
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +6 -8
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +2 -0
- data/lib/active_record/collection_cache_key.rb +10 -5
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +120 -28
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +14 -33
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +13 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +40 -2
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +103 -63
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -90
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +75 -138
- data/lib/active_record/connection_adapters/column.rb +3 -1
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +3 -1
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -6
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +91 -1
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +11 -7
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +79 -65
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +47 -82
- data/lib/active_record/connection_adapters/schema_cache.rb +2 -0
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +19 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -89
- data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
- data/lib/active_record/connection_handling.rb +4 -2
- data/lib/active_record/core.rb +27 -57
- data/lib/active_record/counter_cache.rb +15 -12
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +15 -13
- data/lib/active_record/errors.rb +54 -21
- data/lib/active_record/explain.rb +3 -1
- data/lib/active_record/explain_registry.rb +2 -0
- data/lib/active_record/explain_subscriber.rb +2 -0
- data/lib/active_record/fixture_set/file.rb +2 -0
- data/lib/active_record/fixtures.rb +40 -24
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +6 -5
- data/lib/active_record/integration.rb +58 -19
- data/lib/active_record/internal_metadata.rb +2 -0
- data/lib/active_record/legacy_yaml_adapter.rb +3 -1
- data/lib/active_record/locking/optimistic.rb +31 -20
- data/lib/active_record/locking/pessimistic.rb +10 -7
- data/lib/active_record/log_subscriber.rb +2 -0
- data/lib/active_record/migration.rb +47 -21
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +20 -2
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/model_schema.rb +29 -38
- data/lib/active_record/nested_attributes.rb +18 -6
- data/lib/active_record/no_touching.rb +3 -1
- data/lib/active_record/null_relation.rb +2 -0
- data/lib/active_record/persistence.rb +184 -40
- data/lib/active_record/query_cache.rb +17 -12
- data/lib/active_record/querying.rb +3 -1
- data/lib/active_record/railtie.rb +54 -1
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +2 -0
- data/lib/active_record/railties/databases.rake +41 -28
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +100 -182
- data/lib/active_record/relation.rb +61 -193
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/calculations.rb +40 -23
- data/lib/active_record/relation/delegation.rb +10 -27
- data/lib/active_record/relation/finder_methods.rb +53 -49
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +22 -19
- data/lib/active_record/relation/predicate_builder.rb +42 -79
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +54 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/query_attribute.rb +9 -2
- data/lib/active_record/relation/query_methods.rb +80 -69
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +2 -0
- data/lib/active_record/relation/where_clause.rb +50 -67
- data/lib/active_record/relation/where_clause_factory.rb +4 -46
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +15 -9
- data/lib/active_record/schema.rb +3 -1
- data/lib/active_record/schema_dumper.rb +24 -23
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +15 -7
- data/lib/active_record/secure_token.rb +2 -0
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +22 -12
- data/lib/active_record/store.rb +2 -0
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +3 -1
- data/lib/active_record/tasks/database_tasks.rb +23 -12
- data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
- data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +5 -12
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -7
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type.rb +4 -1
- data/lib/active_record/type/adapter_specific_registry.rb +2 -0
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +2 -4
- data/lib/active_record/type/text.rb +2 -0
- data/lib/active_record/type/time.rb +2 -0
- data/lib/active_record/type/type_map.rb +2 -0
- data/lib/active_record/type/unsigned_integer.rb +2 -0
- data/lib/active_record/type_caster.rb +2 -0
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +2 -0
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +2 -0
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +2 -0
- data/lib/active_record/validations/uniqueness.rb +36 -6
- data/lib/active_record/version.rb +2 -0
- data/lib/rails/generators/active_record.rb +3 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +2 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +25 -38
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -15
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -18
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute_mutation_tracker.rb +0 -122
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/attribute_set/builder.rb +0 -126
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
- data/lib/active_record/type/internal/abstract_json.rb +0 -37
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# = Active Record Query Cache
|
3
5
|
class QueryCache
|
@@ -5,35 +7,38 @@ module ActiveRecord
|
|
5
7
|
# Enable the query cache within the block if Active Record is configured.
|
6
8
|
# If it's not, it will execute the given block.
|
7
9
|
def cache(&block)
|
8
|
-
if
|
9
|
-
connection.cache(&block)
|
10
|
-
else
|
10
|
+
if configurations.empty?
|
11
11
|
yield
|
12
|
+
else
|
13
|
+
connection.cache(&block)
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
15
17
|
# Disable the query cache within the block if Active Record is configured.
|
16
18
|
# If it's not, it will execute the given block.
|
17
19
|
def uncached(&block)
|
18
|
-
if
|
19
|
-
connection.uncached(&block)
|
20
|
-
else
|
20
|
+
if configurations.empty?
|
21
21
|
yield
|
22
|
+
else
|
23
|
+
connection.uncached(&block)
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
28
|
def self.run
|
27
|
-
|
28
|
-
|
29
|
+
ActiveRecord::Base.connection_handler.connection_pool_list.map do |pool|
|
30
|
+
caching_was_enabled = pool.query_cache_enabled
|
29
31
|
|
30
|
-
|
32
|
+
pool.enable_query_cache!
|
31
33
|
|
32
|
-
|
34
|
+
[pool, caching_was_enabled]
|
35
|
+
end
|
33
36
|
end
|
34
37
|
|
35
|
-
def self.complete(
|
36
|
-
|
38
|
+
def self.complete(caching_pools)
|
39
|
+
caching_pools.each do |pool, caching_was_enabled|
|
40
|
+
pool.disable_query_cache! unless caching_was_enabled
|
41
|
+
end
|
37
42
|
|
38
43
|
ActiveRecord::Base.connection_handler.connection_pool_list.each do |pool|
|
39
44
|
pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Querying
|
3
5
|
delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :none?, :one?, to: :all
|
@@ -5,7 +7,7 @@ module ActiveRecord
|
|
5
7
|
delegate :first_or_create, :first_or_create!, :first_or_initialize, to: :all
|
6
8
|
delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, to: :all
|
7
9
|
delegate :find_by, :find_by!, to: :all
|
8
|
-
delegate :
|
10
|
+
delegate :destroy_all, :delete_all, :update_all, to: :all
|
9
11
|
delegate :find_each, :find_in_batches, :in_batches, to: :all
|
10
12
|
delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
|
11
13
|
:where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly, :extending,
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_record"
|
2
4
|
require "rails"
|
3
5
|
require "active_model/railtie"
|
@@ -26,6 +28,9 @@ module ActiveRecord
|
|
26
28
|
config.active_record.use_schema_cache_dump = true
|
27
29
|
config.active_record.maintain_test_schema = true
|
28
30
|
|
31
|
+
config.active_record.sqlite3 = ActiveSupport::OrderedOptions.new
|
32
|
+
config.active_record.sqlite3.represent_boolean_as_integer = nil
|
33
|
+
|
29
34
|
config.eager_load_namespaces << ActiveRecord
|
30
35
|
|
31
36
|
rake_tasks do
|
@@ -108,7 +113,9 @@ module ActiveRecord
|
|
108
113
|
|
109
114
|
initializer "active_record.set_configs" do |app|
|
110
115
|
ActiveSupport.on_load(:active_record) do
|
111
|
-
app.config.active_record.
|
116
|
+
configs = app.config.active_record.dup
|
117
|
+
configs.delete(:sqlite3)
|
118
|
+
configs.each do |k, v|
|
112
119
|
send "#{k}=", v
|
113
120
|
end
|
114
121
|
end
|
@@ -166,5 +173,51 @@ end_warning
|
|
166
173
|
path = app.paths["db"].first
|
167
174
|
config.watchable_files.concat ["#{path}/schema.rb", "#{path}/structure.sql"]
|
168
175
|
end
|
176
|
+
|
177
|
+
initializer "active_record.clear_active_connections" do
|
178
|
+
config.after_initialize do
|
179
|
+
ActiveSupport.on_load(:active_record) do
|
180
|
+
# Ideally the application doesn't connect to the database during boot,
|
181
|
+
# but sometimes it does. In case it did, we want to empty out the
|
182
|
+
# connection pools so that a non-database-using process (e.g. a master
|
183
|
+
# process in a forking server model) doesn't retain a needless
|
184
|
+
# connection. If it was needed, the incremental cost of reestablishing
|
185
|
+
# this connection is trivial: the rest of the pool would need to be
|
186
|
+
# populated anyway.
|
187
|
+
|
188
|
+
clear_active_connections!
|
189
|
+
flush_idle_connections!
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
initializer "active_record.check_represent_sqlite3_boolean_as_integer" do
|
195
|
+
config.after_initialize do
|
196
|
+
ActiveSupport.on_load(:active_record_sqlite3adapter) do
|
197
|
+
represent_boolean_as_integer = Rails.application.config.active_record.sqlite3.delete(:represent_boolean_as_integer)
|
198
|
+
unless represent_boolean_as_integer.nil?
|
199
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = represent_boolean_as_integer
|
200
|
+
end
|
201
|
+
|
202
|
+
unless ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer
|
203
|
+
ActiveSupport::Deprecation.warn <<-MSG
|
204
|
+
Leaving `ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer`
|
205
|
+
set to false is deprecated. SQLite databases have used 't' and 'f' to serialize
|
206
|
+
boolean values and must have old data converted to 1 and 0 (its native boolean
|
207
|
+
serialization) before setting this flag to true. Conversion can be accomplished
|
208
|
+
by setting up a rake task which runs
|
209
|
+
|
210
|
+
ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
|
211
|
+
ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
|
212
|
+
|
213
|
+
for all models and all boolean columns, after which the flag must be set to
|
214
|
+
true by adding the following to your application.rb file:
|
215
|
+
|
216
|
+
Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
|
217
|
+
MSG
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
169
222
|
end
|
170
223
|
end
|
@@ -1,17 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_record"
|
2
4
|
|
3
5
|
db_namespace = namespace :db do
|
4
6
|
desc "Set the environment value for the database"
|
5
|
-
task "environment:set" =>
|
7
|
+
task "environment:set" => :load_config do
|
6
8
|
ActiveRecord::InternalMetadata.create_table
|
7
9
|
ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment
|
8
10
|
end
|
9
11
|
|
10
|
-
task check_protected_environments:
|
12
|
+
task check_protected_environments: :load_config do
|
11
13
|
ActiveRecord::Tasks::DatabaseTasks.check_protected_environments!
|
12
14
|
end
|
13
15
|
|
14
|
-
task :
|
16
|
+
task load_config: :environment do
|
15
17
|
ActiveRecord::Base.configurations = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
|
16
18
|
ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
|
17
19
|
end
|
@@ -54,7 +56,7 @@ db_namespace = namespace :db do
|
|
54
56
|
end
|
55
57
|
|
56
58
|
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
|
57
|
-
task migrate:
|
59
|
+
task migrate: :load_config do
|
58
60
|
ActiveRecord::Tasks::DatabaseTasks.migrate
|
59
61
|
db_namespace["_dump"].invoke
|
60
62
|
end
|
@@ -76,7 +78,7 @@ db_namespace = namespace :db do
|
|
76
78
|
|
77
79
|
namespace :migrate do
|
78
80
|
# desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
|
79
|
-
task redo:
|
81
|
+
task redo: :load_config do
|
80
82
|
raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
|
81
83
|
|
82
84
|
if ENV["VERSION"]
|
@@ -92,24 +94,35 @@ db_namespace = namespace :db do
|
|
92
94
|
task reset: ["db:drop", "db:create", "db:migrate"]
|
93
95
|
|
94
96
|
# desc 'Runs the "up" for a given migration VERSION.'
|
95
|
-
task up:
|
97
|
+
task up: :load_config do
|
96
98
|
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
97
99
|
|
98
|
-
|
99
|
-
|
100
|
+
ActiveRecord::Tasks::DatabaseTasks.check_target_version
|
101
|
+
|
102
|
+
ActiveRecord::Migrator.run(
|
103
|
+
:up,
|
104
|
+
ActiveRecord::Tasks::DatabaseTasks.migrations_paths,
|
105
|
+
ActiveRecord::Tasks::DatabaseTasks.target_version
|
106
|
+
)
|
100
107
|
db_namespace["_dump"].invoke
|
101
108
|
end
|
102
109
|
|
103
110
|
# desc 'Runs the "down" for a given migration VERSION.'
|
104
|
-
task down:
|
111
|
+
task down: :load_config do
|
105
112
|
raise "VERSION is required - To go down one migration, use db:rollback" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
106
|
-
|
107
|
-
ActiveRecord::
|
113
|
+
|
114
|
+
ActiveRecord::Tasks::DatabaseTasks.check_target_version
|
115
|
+
|
116
|
+
ActiveRecord::Migrator.run(
|
117
|
+
:down,
|
118
|
+
ActiveRecord::Tasks::DatabaseTasks.migrations_paths,
|
119
|
+
ActiveRecord::Tasks::DatabaseTasks.target_version
|
120
|
+
)
|
108
121
|
db_namespace["_dump"].invoke
|
109
122
|
end
|
110
123
|
|
111
124
|
desc "Display status of migrations"
|
112
|
-
task status:
|
125
|
+
task status: :load_config do
|
113
126
|
unless ActiveRecord::SchemaMigration.table_exists?
|
114
127
|
abort "Schema migrations table does not exist yet."
|
115
128
|
end
|
@@ -127,14 +140,14 @@ db_namespace = namespace :db do
|
|
127
140
|
end
|
128
141
|
|
129
142
|
desc "Rolls the schema back to the previous version (specify steps w/ STEP=n)."
|
130
|
-
task rollback:
|
143
|
+
task rollback: :load_config do
|
131
144
|
step = ENV["STEP"] ? ENV["STEP"].to_i : 1
|
132
145
|
ActiveRecord::Migrator.rollback(ActiveRecord::Tasks::DatabaseTasks.migrations_paths, step)
|
133
146
|
db_namespace["_dump"].invoke
|
134
147
|
end
|
135
148
|
|
136
149
|
# desc 'Pushes the schema to the next version (specify steps w/ STEP=n).'
|
137
|
-
task forward:
|
150
|
+
task forward: :load_config do
|
138
151
|
step = ENV["STEP"] ? ENV["STEP"].to_i : 1
|
139
152
|
ActiveRecord::Migrator.forward(ActiveRecord::Tasks::DatabaseTasks.migrations_paths, step)
|
140
153
|
db_namespace["_dump"].invoke
|
@@ -144,12 +157,12 @@ db_namespace = namespace :db do
|
|
144
157
|
task reset: [ "db:drop", "db:setup" ]
|
145
158
|
|
146
159
|
# desc "Retrieves the charset for the current environment's database"
|
147
|
-
task charset:
|
160
|
+
task charset: :load_config do
|
148
161
|
puts ActiveRecord::Tasks::DatabaseTasks.charset_current
|
149
162
|
end
|
150
163
|
|
151
164
|
# desc "Retrieves the collation for the current environment's database"
|
152
|
-
task collation:
|
165
|
+
task collation: :load_config do
|
153
166
|
begin
|
154
167
|
puts ActiveRecord::Tasks::DatabaseTasks.collation_current
|
155
168
|
rescue NoMethodError
|
@@ -158,12 +171,12 @@ db_namespace = namespace :db do
|
|
158
171
|
end
|
159
172
|
|
160
173
|
desc "Retrieves the current schema version number"
|
161
|
-
task version:
|
174
|
+
task version: :load_config do
|
162
175
|
puts "Current version: #{ActiveRecord::Migrator.current_version}"
|
163
176
|
end
|
164
177
|
|
165
178
|
# desc "Raises an error if there are pending migrations"
|
166
|
-
task abort_if_pending_migrations:
|
179
|
+
task abort_if_pending_migrations: :load_config do
|
167
180
|
pending_migrations = ActiveRecord::Migrator.open(ActiveRecord::Tasks::DatabaseTasks.migrations_paths).pending_migrations
|
168
181
|
|
169
182
|
if pending_migrations.any?
|
@@ -186,7 +199,7 @@ db_namespace = namespace :db do
|
|
186
199
|
|
187
200
|
namespace :fixtures do
|
188
201
|
desc "Loads fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
|
189
|
-
task load:
|
202
|
+
task load: :load_config do
|
190
203
|
require "active_record/fixtures"
|
191
204
|
|
192
205
|
base_dir = ActiveRecord::Tasks::DatabaseTasks.fixtures_path
|
@@ -208,7 +221,7 @@ db_namespace = namespace :db do
|
|
208
221
|
end
|
209
222
|
|
210
223
|
# desc "Search for a fixture given a LABEL or ID. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
|
211
|
-
task identify:
|
224
|
+
task identify: :load_config do
|
212
225
|
require "active_record/fixtures"
|
213
226
|
|
214
227
|
label, id = ENV["LABEL"], ENV["ID"]
|
@@ -234,7 +247,7 @@ db_namespace = namespace :db do
|
|
234
247
|
|
235
248
|
namespace :schema do
|
236
249
|
desc "Creates a db/schema.rb file that is portable against any DB supported by Active Record"
|
237
|
-
task dump:
|
250
|
+
task dump: :load_config do
|
238
251
|
require "active_record/schema_dumper"
|
239
252
|
filename = ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema.rb")
|
240
253
|
File.open(filename, "w:utf-8") do |file|
|
@@ -244,7 +257,7 @@ db_namespace = namespace :db do
|
|
244
257
|
end
|
245
258
|
|
246
259
|
desc "Loads a schema.rb file into the database"
|
247
|
-
task load: [:
|
260
|
+
task load: [:load_config, :check_protected_environments] do
|
248
261
|
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:ruby, ENV["SCHEMA"])
|
249
262
|
end
|
250
263
|
|
@@ -254,14 +267,14 @@ db_namespace = namespace :db do
|
|
254
267
|
|
255
268
|
namespace :cache do
|
256
269
|
desc "Creates a db/schema_cache.yml file."
|
257
|
-
task dump:
|
270
|
+
task dump: :load_config do
|
258
271
|
conn = ActiveRecord::Base.connection
|
259
272
|
filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.yml")
|
260
273
|
ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(conn, filename)
|
261
274
|
end
|
262
275
|
|
263
276
|
desc "Clears a db/schema_cache.yml file."
|
264
|
-
task clear:
|
277
|
+
task clear: :load_config do
|
265
278
|
filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.yml")
|
266
279
|
rm_f filename, verbose: false
|
267
280
|
end
|
@@ -271,7 +284,7 @@ db_namespace = namespace :db do
|
|
271
284
|
|
272
285
|
namespace :structure do
|
273
286
|
desc "Dumps the database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
|
274
|
-
task dump:
|
287
|
+
task dump: :load_config do
|
275
288
|
filename = ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql")
|
276
289
|
current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
|
277
290
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename)
|
@@ -286,7 +299,7 @@ db_namespace = namespace :db do
|
|
286
299
|
end
|
287
300
|
|
288
301
|
desc "Recreates the databases from the structure.sql file"
|
289
|
-
task load: [:
|
302
|
+
task load: [:load_config, :check_protected_environments] do
|
290
303
|
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:sql, ENV["SCHEMA"])
|
291
304
|
end
|
292
305
|
|
@@ -325,12 +338,12 @@ db_namespace = namespace :db do
|
|
325
338
|
end
|
326
339
|
|
327
340
|
# desc "Empty the test database"
|
328
|
-
task purge: %w(
|
341
|
+
task purge: %w(load_config check_protected_environments) do
|
329
342
|
ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations["test"]
|
330
343
|
end
|
331
344
|
|
332
345
|
# desc 'Load the test schema'
|
333
|
-
task prepare:
|
346
|
+
task prepare: :load_config do
|
334
347
|
unless ActiveRecord::Base.configurations.blank?
|
335
348
|
db_namespace["test:load"].invoke
|
336
349
|
end
|
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ReadonlyAttributes
|
3
5
|
extend ActiveSupport::Concern
|
4
6
|
|
5
7
|
included do
|
6
|
-
class_attribute :_attr_readonly, instance_accessor: false
|
7
|
-
self._attr_readonly = []
|
8
|
+
class_attribute :_attr_readonly, instance_accessor: false, default: []
|
8
9
|
end
|
9
10
|
|
10
11
|
module ClassMethods
|
@@ -1,6 +1,7 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "active_support/core_ext/string/filters"
|
3
|
-
require "
|
4
|
+
require "concurrent/map"
|
4
5
|
|
5
6
|
module ActiveRecord
|
6
7
|
# = Active Record Reflection
|
@@ -8,10 +9,8 @@ module ActiveRecord
|
|
8
9
|
extend ActiveSupport::Concern
|
9
10
|
|
10
11
|
included do
|
11
|
-
class_attribute :_reflections, instance_writer: false
|
12
|
-
class_attribute :aggregate_reflections, instance_writer: false
|
13
|
-
self._reflections = {}
|
14
|
-
self.aggregate_reflections = {}
|
12
|
+
class_attribute :_reflections, instance_writer: false, default: {}
|
13
|
+
class_attribute :aggregate_reflections, instance_writer: false, default: {}
|
15
14
|
end
|
16
15
|
|
17
16
|
def self.create(macro, name, scope, options, ar)
|
@@ -35,8 +34,7 @@ module ActiveRecord
|
|
35
34
|
|
36
35
|
def self.add_reflection(ar, name, reflection)
|
37
36
|
ar.clear_reflections_cache
|
38
|
-
|
39
|
-
ar._reflections = ar._reflections.except(name).merge!(name => reflection)
|
37
|
+
ar._reflections = ar._reflections.merge(name.to_s => reflection)
|
40
38
|
end
|
41
39
|
|
42
40
|
def self.add_aggregate_reflection(ar, name, reflection)
|
@@ -139,7 +137,7 @@ module ActiveRecord
|
|
139
137
|
# HasAndBelongsToManyReflection
|
140
138
|
# ThroughReflection
|
141
139
|
# PolymorphicReflection
|
142
|
-
#
|
140
|
+
# RuntimeReflection
|
143
141
|
class AbstractReflection # :nodoc:
|
144
142
|
def through_reflection?
|
145
143
|
false
|
@@ -155,14 +153,6 @@ module ActiveRecord
|
|
155
153
|
klass.new(attributes, &block)
|
156
154
|
end
|
157
155
|
|
158
|
-
def quoted_table_name
|
159
|
-
klass.quoted_table_name
|
160
|
-
end
|
161
|
-
|
162
|
-
def primary_key_type
|
163
|
-
klass.type_for_attribute(klass.primary_key)
|
164
|
-
end
|
165
|
-
|
166
156
|
# Returns the class name for the macro.
|
167
157
|
#
|
168
158
|
# <tt>composed_of :balance, class_name: 'Money'</tt> returns <tt>'Money'</tt>
|
@@ -174,7 +164,7 @@ module ActiveRecord
|
|
174
164
|
JoinKeys = Struct.new(:key, :foreign_key) # :nodoc:
|
175
165
|
|
176
166
|
def join_keys
|
177
|
-
get_join_keys
|
167
|
+
@join_keys ||= get_join_keys(klass)
|
178
168
|
end
|
179
169
|
|
180
170
|
# Returns a list of scopes that should be applied for this Reflection
|
@@ -183,22 +173,34 @@ module ActiveRecord
|
|
183
173
|
scope ? [scope] : []
|
184
174
|
end
|
185
175
|
|
186
|
-
def
|
187
|
-
|
176
|
+
def build_join_constraint(table, foreign_table)
|
177
|
+
key = join_keys.key
|
178
|
+
foreign_key = join_keys.foreign_key
|
179
|
+
|
180
|
+
constraint = table[key].eq(foreign_table[foreign_key])
|
181
|
+
|
182
|
+
if klass.finder_needs_type_condition?
|
183
|
+
table.create_and([constraint, klass.send(:type_condition, table)])
|
184
|
+
else
|
185
|
+
constraint
|
186
|
+
end
|
188
187
|
end
|
189
|
-
deprecate :scope_chain
|
190
188
|
|
191
|
-
def join_scope(table)
|
189
|
+
def join_scope(table, foreign_klass)
|
192
190
|
predicate_builder = predicate_builder(table)
|
193
191
|
scope_chain_items = join_scopes(table, predicate_builder)
|
194
192
|
klass_scope = klass_join_scope(table, predicate_builder)
|
195
193
|
|
196
|
-
|
194
|
+
if type
|
195
|
+
klass_scope.where!(type => foreign_klass.base_class.sti_name)
|
196
|
+
end
|
197
|
+
|
198
|
+
scope_chain_items.inject(klass_scope, &:merge!)
|
197
199
|
end
|
198
200
|
|
199
201
|
def join_scopes(table, predicate_builder) # :nodoc:
|
200
202
|
if scope
|
201
|
-
[build_scope(table, predicate_builder)
|
203
|
+
[scope_for(build_scope(table, predicate_builder))]
|
202
204
|
else
|
203
205
|
[]
|
204
206
|
end
|
@@ -210,7 +212,7 @@ module ActiveRecord
|
|
210
212
|
end
|
211
213
|
|
212
214
|
def constraints
|
213
|
-
chain.
|
215
|
+
chain.flat_map(&:scopes)
|
214
216
|
end
|
215
217
|
|
216
218
|
def counter_cache_column
|
@@ -284,24 +286,33 @@ module ActiveRecord
|
|
284
286
|
end
|
285
287
|
|
286
288
|
def get_join_keys(association_klass)
|
287
|
-
JoinKeys.new(
|
289
|
+
JoinKeys.new(join_primary_key(association_klass), join_foreign_key)
|
288
290
|
end
|
289
291
|
|
290
292
|
def build_scope(table, predicate_builder = predicate_builder(table))
|
291
293
|
Relation.create(klass, table, predicate_builder)
|
292
294
|
end
|
293
295
|
|
296
|
+
def join_primary_key(_)
|
297
|
+
foreign_key
|
298
|
+
end
|
299
|
+
|
300
|
+
def join_foreign_key
|
301
|
+
active_record_primary_key
|
302
|
+
end
|
303
|
+
|
304
|
+
protected
|
305
|
+
def actual_source_reflection # FIXME: this is a horrible name
|
306
|
+
self
|
307
|
+
end
|
308
|
+
|
294
309
|
private
|
295
310
|
def predicate_builder(table)
|
296
311
|
PredicateBuilder.new(TableMetadata.new(klass, table))
|
297
312
|
end
|
298
313
|
|
299
|
-
def
|
300
|
-
|
301
|
-
end
|
302
|
-
|
303
|
-
def join_fk
|
304
|
-
active_record_primary_key
|
314
|
+
def primary_key(klass)
|
315
|
+
klass.primary_key || raise(UnknownPrimaryKey.new(klass))
|
305
316
|
end
|
306
317
|
end
|
307
318
|
|
@@ -348,6 +359,17 @@ module ActiveRecord
|
|
348
359
|
#
|
349
360
|
# <tt>composed_of :balance, class_name: 'Money'</tt> returns the Money class
|
350
361
|
# <tt>has_many :clients</tt> returns the Client class
|
362
|
+
#
|
363
|
+
# class Company < ActiveRecord::Base
|
364
|
+
# has_many :clients
|
365
|
+
# end
|
366
|
+
#
|
367
|
+
# Company.reflect_on_association(:clients).klass
|
368
|
+
# # => Client
|
369
|
+
#
|
370
|
+
# <b>Note:</b> Do not call +klass.new+ or +klass.create+ to instantiate
|
371
|
+
# a new association object. Use +build_association+ or +create_association+
|
372
|
+
# instead. This allows plugins to hook into association object creation.
|
351
373
|
def klass
|
352
374
|
@klass ||= compute_class(class_name)
|
353
375
|
end
|
@@ -366,8 +388,8 @@ module ActiveRecord
|
|
366
388
|
active_record == other_aggregation.active_record
|
367
389
|
end
|
368
390
|
|
369
|
-
def scope_for(
|
370
|
-
|
391
|
+
def scope_for(relation, owner = nil)
|
392
|
+
relation.instance_exec(owner, &scope) || relation
|
371
393
|
end
|
372
394
|
|
373
395
|
private
|
@@ -388,22 +410,6 @@ module ActiveRecord
|
|
388
410
|
# Holds all the metadata about an association as it was specified in the
|
389
411
|
# Active Record class.
|
390
412
|
class AssociationReflection < MacroReflection #:nodoc:
|
391
|
-
# Returns the target association's class.
|
392
|
-
#
|
393
|
-
# class Author < ActiveRecord::Base
|
394
|
-
# has_many :books
|
395
|
-
# end
|
396
|
-
#
|
397
|
-
# Author.reflect_on_association(:books).klass
|
398
|
-
# # => Book
|
399
|
-
#
|
400
|
-
# <b>Note:</b> Do not call +klass.new+ or +klass.create+ to instantiate
|
401
|
-
# a new association object. Use +build_association+ or +create_association+
|
402
|
-
# instead. This allows plugins to hook into association object creation.
|
403
|
-
def klass
|
404
|
-
@klass ||= compute_class(class_name)
|
405
|
-
end
|
406
|
-
|
407
413
|
def compute_class(name)
|
408
414
|
active_record.send(:compute_type, name)
|
409
415
|
end
|
@@ -414,31 +420,21 @@ module ActiveRecord
|
|
414
420
|
def initialize(name, scope, options, active_record)
|
415
421
|
super
|
416
422
|
@type = options[:as] && (options[:foreign_type] || "#{options[:as]}_type")
|
417
|
-
@foreign_type = options[:foreign_type] || "#{name}_type"
|
423
|
+
@foreign_type = options[:polymorphic] && (options[:foreign_type] || "#{name}_type")
|
418
424
|
@constructable = calculate_constructable(macro, options)
|
419
|
-
@association_scope_cache =
|
420
|
-
@scope_lock = Mutex.new
|
425
|
+
@association_scope_cache = Concurrent::Map.new
|
421
426
|
|
422
427
|
if options[:class_name] && options[:class_name].class == Class
|
423
|
-
|
424
|
-
Passing a class to the `class_name` is deprecated and will raise
|
425
|
-
an ArgumentError in Rails 5.2. It eagerloads more classes than
|
426
|
-
necessary and potentially creates circular dependencies.
|
427
|
-
|
428
|
-
Please pass the class name as a string:
|
429
|
-
`#{macro} :#{name}, class_name: '#{options[:class_name]}'`
|
430
|
-
MSG
|
428
|
+
raise ArgumentError, "A class was passed to `:class_name` but we are expecting a string."
|
431
429
|
end
|
432
430
|
end
|
433
431
|
|
434
|
-
def association_scope_cache(conn, owner)
|
432
|
+
def association_scope_cache(conn, owner, &block)
|
435
433
|
key = conn.prepared_statements
|
436
434
|
if polymorphic?
|
437
435
|
key = [key, owner._read_attribute(@foreign_type)]
|
438
436
|
end
|
439
|
-
@association_scope_cache
|
440
|
-
@association_scope_cache[key] ||= yield
|
441
|
-
}
|
437
|
+
@association_scope_cache.compute_if_absent(key) { StatementCache.create(conn, &block) }
|
442
438
|
end
|
443
439
|
|
444
440
|
def constructable? # :nodoc:
|
@@ -488,7 +484,7 @@ module ActiveRecord
|
|
488
484
|
alias :check_eager_loadable! :check_preloadable!
|
489
485
|
|
490
486
|
def join_id_for(owner) # :nodoc:
|
491
|
-
owner[
|
487
|
+
owner[join_foreign_key]
|
492
488
|
end
|
493
489
|
|
494
490
|
def through_reflection
|
@@ -571,7 +567,7 @@ module ActiveRecord
|
|
571
567
|
end
|
572
568
|
|
573
569
|
VALID_AUTOMATIC_INVERSE_MACROS = [:has_many, :has_one, :belongs_to]
|
574
|
-
INVALID_AUTOMATIC_INVERSE_OPTIONS = [:conditions, :through, :
|
570
|
+
INVALID_AUTOMATIC_INVERSE_OPTIONS = [:conditions, :through, :foreign_key]
|
575
571
|
|
576
572
|
def add_as_source(seed)
|
577
573
|
seed
|
@@ -589,12 +585,6 @@ module ActiveRecord
|
|
589
585
|
Array(options[:extend])
|
590
586
|
end
|
591
587
|
|
592
|
-
protected
|
593
|
-
|
594
|
-
def actual_source_reflection # FIXME: this is a horrible name
|
595
|
-
self
|
596
|
-
end
|
597
|
-
|
598
588
|
private
|
599
589
|
|
600
590
|
def calculate_constructable(macro, options)
|
@@ -640,7 +630,7 @@ module ActiveRecord
|
|
640
630
|
# from calling +klass+, +reflection+ will already be set to false.
|
641
631
|
def valid_inverse_reflection?(reflection)
|
642
632
|
reflection &&
|
643
|
-
klass
|
633
|
+
klass <= reflection.active_record &&
|
644
634
|
can_find_inverse_of_automatically?(reflection)
|
645
635
|
end
|
646
636
|
|
@@ -648,9 +638,8 @@ module ActiveRecord
|
|
648
638
|
# us from being able to guess the inverse automatically. First, the
|
649
639
|
# <tt>inverse_of</tt> option cannot be set to false. Second, we must
|
650
640
|
# have <tt>has_many</tt>, <tt>has_one</tt>, <tt>belongs_to</tt> associations.
|
651
|
-
# Third, we must not have options such as <tt>:
|
652
|
-
#
|
653
|
-
# inverse association.
|
641
|
+
# Third, we must not have options such as <tt>:foreign_key</tt>
|
642
|
+
# which prevent us from correctly guessing the inverse association.
|
654
643
|
#
|
655
644
|
# Anything with a scope can additionally ruin our attempt at finding an
|
656
645
|
# inverse, so we exclude reflections with scopes.
|
@@ -680,10 +669,6 @@ module ActiveRecord
|
|
680
669
|
def derive_join_table
|
681
670
|
ModelSchema.derive_join_table_name active_record.table_name, klass.table_name
|
682
671
|
end
|
683
|
-
|
684
|
-
def primary_key(klass)
|
685
|
-
klass.primary_key || raise(UnknownPrimaryKey.new(klass))
|
686
|
-
end
|
687
672
|
end
|
688
673
|
|
689
674
|
class HasManyReflection < AssociationReflection # :nodoc:
|
@@ -737,8 +722,12 @@ module ActiveRecord
|
|
737
722
|
end
|
738
723
|
end
|
739
724
|
|
740
|
-
def
|
741
|
-
|
725
|
+
def join_primary_key(klass)
|
726
|
+
polymorphic? ? association_primary_key(klass) : association_primary_key
|
727
|
+
end
|
728
|
+
|
729
|
+
def join_foreign_key
|
730
|
+
foreign_key
|
742
731
|
end
|
743
732
|
|
744
733
|
private
|
@@ -746,21 +735,9 @@ module ActiveRecord
|
|
746
735
|
def calculate_constructable(macro, options)
|
747
736
|
!polymorphic?
|
748
737
|
end
|
749
|
-
|
750
|
-
def join_fk
|
751
|
-
foreign_key
|
752
|
-
end
|
753
|
-
|
754
|
-
def join_pk(klass)
|
755
|
-
polymorphic? ? association_primary_key(klass) : association_primary_key
|
756
|
-
end
|
757
738
|
end
|
758
739
|
|
759
740
|
class HasAndBelongsToManyReflection < AssociationReflection # :nodoc:
|
760
|
-
def initialize(name, scope, options, active_record)
|
761
|
-
super
|
762
|
-
end
|
763
|
-
|
764
741
|
def macro; :has_and_belongs_to_many; end
|
765
742
|
|
766
743
|
def collection?
|
@@ -771,8 +748,7 @@ module ActiveRecord
|
|
771
748
|
# Holds all the metadata about a :through association as it was specified
|
772
749
|
# in the Active Record class.
|
773
750
|
class ThroughReflection < AbstractReflection #:nodoc:
|
774
|
-
|
775
|
-
delegate :foreign_key, :foreign_type, :association_foreign_key,
|
751
|
+
delegate :foreign_key, :foreign_type, :association_foreign_key, :join_id_for,
|
776
752
|
:active_record_primary_key, :type, :get_join_keys, to: :source_reflection
|
777
753
|
|
778
754
|
def initialize(delegate_reflection)
|
@@ -863,10 +839,6 @@ module ActiveRecord
|
|
863
839
|
source_reflection.join_scopes(table, predicate_builder) + super
|
864
840
|
end
|
865
841
|
|
866
|
-
def source_type_scope
|
867
|
-
through_reflection.klass.where(foreign_type => options[:source_type])
|
868
|
-
end
|
869
|
-
|
870
842
|
def has_scope?
|
871
843
|
scope || options[:source_type] ||
|
872
844
|
source_reflection.has_scope? ||
|
@@ -935,10 +907,6 @@ module ActiveRecord
|
|
935
907
|
through_reflection.options
|
936
908
|
end
|
937
909
|
|
938
|
-
def join_id_for(owner) # :nodoc:
|
939
|
-
source_reflection.join_id_for(owner)
|
940
|
-
end
|
941
|
-
|
942
910
|
def check_validity!
|
943
911
|
if through_reflection.nil?
|
944
912
|
raise HasManyThroughAssociationNotFoundError.new(active_record.name, self)
|
@@ -997,23 +965,23 @@ module ActiveRecord
|
|
997
965
|
collect_join_reflections(seed + [self])
|
998
966
|
end
|
999
967
|
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
else
|
1005
|
-
through_reflection.add_as_through a
|
1006
|
-
end
|
1007
|
-
end
|
1008
|
-
|
1009
|
-
private
|
968
|
+
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
969
|
+
# Workaround for Ruby 2.2 "private attribute?" warning.
|
970
|
+
protected
|
971
|
+
attr_reader :delegate_reflection
|
1010
972
|
|
1011
973
|
def actual_source_reflection # FIXME: this is a horrible name
|
1012
|
-
source_reflection.
|
974
|
+
source_reflection.actual_source_reflection
|
1013
975
|
end
|
1014
976
|
|
1015
|
-
|
1016
|
-
|
977
|
+
private
|
978
|
+
def collect_join_reflections(seed)
|
979
|
+
a = source_reflection.add_as_source seed
|
980
|
+
if options[:source_type]
|
981
|
+
through_reflection.add_as_polymorphic_through self, a
|
982
|
+
else
|
983
|
+
through_reflection.add_as_through a
|
984
|
+
end
|
1017
985
|
end
|
1018
986
|
|
1019
987
|
def inverse_name; delegate_reflection.send(:inverse_name); end
|
@@ -1030,66 +998,32 @@ module ActiveRecord
|
|
1030
998
|
end
|
1031
999
|
|
1032
1000
|
class PolymorphicReflection < AbstractReflection # :nodoc:
|
1001
|
+
delegate :klass, :scope, :plural_name, :type, :get_join_keys, :scope_for, to: :@reflection
|
1002
|
+
|
1033
1003
|
def initialize(reflection, previous_reflection)
|
1034
1004
|
@reflection = reflection
|
1035
1005
|
@previous_reflection = previous_reflection
|
1036
1006
|
end
|
1037
1007
|
|
1038
|
-
def scopes
|
1039
|
-
scopes = @previous_reflection.scopes
|
1040
|
-
if @previous_reflection.options[:source_type]
|
1041
|
-
scopes + [@previous_reflection.source_type_scope]
|
1042
|
-
else
|
1043
|
-
scopes
|
1044
|
-
end
|
1045
|
-
end
|
1046
|
-
|
1047
1008
|
def join_scopes(table, predicate_builder) # :nodoc:
|
1048
1009
|
scopes = @previous_reflection.join_scopes(table, predicate_builder) + super
|
1049
|
-
|
1050
|
-
scopes + [@previous_reflection.source_type_scope]
|
1051
|
-
else
|
1052
|
-
scopes
|
1053
|
-
end
|
1054
|
-
end
|
1055
|
-
|
1056
|
-
def klass
|
1057
|
-
@reflection.klass
|
1058
|
-
end
|
1059
|
-
|
1060
|
-
def scope
|
1061
|
-
@reflection.scope
|
1062
|
-
end
|
1063
|
-
|
1064
|
-
def table_name
|
1065
|
-
@reflection.table_name
|
1066
|
-
end
|
1067
|
-
|
1068
|
-
def plural_name
|
1069
|
-
@reflection.plural_name
|
1070
|
-
end
|
1071
|
-
|
1072
|
-
def type
|
1073
|
-
@reflection.type
|
1010
|
+
scopes << build_scope(table, predicate_builder).instance_exec(nil, &source_type_scope)
|
1074
1011
|
end
|
1075
1012
|
|
1076
1013
|
def constraints
|
1077
|
-
@reflection.constraints + [
|
1014
|
+
@reflection.constraints + [source_type_scope]
|
1078
1015
|
end
|
1079
1016
|
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
def get_join_keys(association_klass)
|
1087
|
-
@reflection.get_join_keys(association_klass)
|
1088
|
-
end
|
1017
|
+
private
|
1018
|
+
def source_type_scope
|
1019
|
+
type = @previous_reflection.foreign_type
|
1020
|
+
source_type = @previous_reflection.options[:source_type]
|
1021
|
+
lambda { |object| where(type => source_type) }
|
1022
|
+
end
|
1089
1023
|
end
|
1090
1024
|
|
1091
|
-
class RuntimeReflection <
|
1092
|
-
|
1025
|
+
class RuntimeReflection < AbstractReflection # :nodoc:
|
1026
|
+
delegate :scope, :type, :constraints, :get_join_keys, to: :@reflection
|
1093
1027
|
|
1094
1028
|
def initialize(reflection, association)
|
1095
1029
|
@reflection = reflection
|
@@ -1100,24 +1034,8 @@ module ActiveRecord
|
|
1100
1034
|
@association.klass
|
1101
1035
|
end
|
1102
1036
|
|
1103
|
-
def
|
1104
|
-
klass.
|
1105
|
-
end
|
1106
|
-
|
1107
|
-
def constraints
|
1108
|
-
@reflection.constraints
|
1109
|
-
end
|
1110
|
-
|
1111
|
-
def source_type_info
|
1112
|
-
@reflection.source_type_info
|
1113
|
-
end
|
1114
|
-
|
1115
|
-
def alias_candidate(name)
|
1116
|
-
"#{plural_name}_#{name}_join"
|
1117
|
-
end
|
1118
|
-
|
1119
|
-
def alias_name
|
1120
|
-
Arel::Table.new(table_name, type_caster: klass.type_caster)
|
1037
|
+
def aliased_table
|
1038
|
+
@aliased_table ||= Arel::Table.new(table_name, type_caster: klass.type_caster)
|
1121
1039
|
end
|
1122
1040
|
|
1123
1041
|
def all_includes; yield; end
|