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,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
|
-
# = Active Record Belongs To Association
|
3
4
|
module Associations
|
5
|
+
# = Active Record Belongs To Association
|
4
6
|
class BelongsToAssociation < SingularAssociation #:nodoc:
|
5
7
|
def handle_dependency
|
6
8
|
target.send(options[:dependent]) if load_target
|
@@ -47,9 +49,9 @@ module ActiveRecord
|
|
47
49
|
def update_counters(by)
|
48
50
|
if require_counter_update? && foreign_key_present?
|
49
51
|
if target && !stale_target?
|
50
|
-
target.increment!(reflection.counter_cache_column, by
|
52
|
+
target.increment!(reflection.counter_cache_column, by)
|
51
53
|
else
|
52
|
-
klass.update_counters(target_id, reflection.counter_cache_column => by
|
54
|
+
klass.update_counters(target_id, reflection.counter_cache_column => by)
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
@@ -65,7 +67,7 @@ module ActiveRecord
|
|
65
67
|
def update_counters_on_replace(record)
|
66
68
|
if require_counter_update? && different_target?(record)
|
67
69
|
owner.instance_variable_set :@_after_replace_counter_called, true
|
68
|
-
record.increment!(reflection.counter_cache_column
|
70
|
+
record.increment!(reflection.counter_cache_column)
|
69
71
|
decrement_counters
|
70
72
|
end
|
71
73
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
|
-
# = Active Record Belongs To Polymorphic Association
|
3
4
|
module Associations
|
5
|
+
# = Active Record Belongs To Polymorphic Association
|
4
6
|
class BelongsToPolymorphicAssociation < BelongsToAssociation #:nodoc:
|
5
7
|
def klass
|
6
8
|
type = owner[reflection.foreign_type]
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This is the parent Association class which defines the variables
|
2
4
|
# used by all associations.
|
3
5
|
#
|
@@ -36,11 +38,6 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
36
38
|
def self.create_reflection(model, name, scope, options, extension = nil)
|
37
39
|
raise ArgumentError, "association names must be a Symbol" unless name.kind_of?(Symbol)
|
38
40
|
|
39
|
-
if scope.is_a?(Hash)
|
40
|
-
options = scope
|
41
|
-
scope = nil
|
42
|
-
end
|
43
|
-
|
44
41
|
validate_options(options)
|
45
42
|
|
46
43
|
scope = build_scope(scope, extension)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord::Associations::Builder # :nodoc:
|
2
4
|
class BelongsTo < SingularAssociation #:nodoc:
|
3
5
|
def self.macro
|
@@ -32,9 +34,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
32
34
|
foreign_key = reflection.foreign_key
|
33
35
|
cache_column = reflection.counter_cache_column
|
34
36
|
|
35
|
-
if (@
|
36
|
-
@_after_create_counter_called = false
|
37
|
-
elsif (@_after_replace_counter_called ||= false)
|
37
|
+
if (@_after_replace_counter_called ||= false)
|
38
38
|
@_after_replace_counter_called = false
|
39
39
|
elsif saved_change_to_attribute?(foreign_key) && !new_record?
|
40
40
|
if reflection.polymorphic?
|
@@ -84,8 +84,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
84
84
|
else
|
85
85
|
klass = association.klass
|
86
86
|
end
|
87
|
-
|
88
|
-
old_record = klass.find_by(primary_key => old_foreign_id)
|
87
|
+
old_record = klass.find_by(klass.primary_key => old_foreign_id)
|
89
88
|
|
90
89
|
if old_record
|
91
90
|
if touch != true
|
@@ -115,13 +114,9 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
115
114
|
BelongsTo.touch_record(record, record.send(changes_method), foreign_key, n, touch, belongs_to_touch_method)
|
116
115
|
}}
|
117
116
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
end
|
122
|
-
|
123
|
-
model.after_update callback.(:saved_changes), if: :saved_changes?
|
124
|
-
model.after_touch callback.(:changes_to_save)
|
117
|
+
model.after_save callback.(:saved_changes), if: :saved_changes?
|
118
|
+
model.after_touch callback.(:changes_to_save)
|
119
|
+
model.after_destroy callback.(:changes_to_save)
|
125
120
|
end
|
126
121
|
|
127
122
|
def self.add_default_callbacks(model, reflection)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord::Associations::Builder # :nodoc:
|
2
4
|
class HasAndBelongsToMany # :nodoc:
|
3
5
|
class JoinTableResolver # :nodoc:
|
@@ -45,7 +47,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
45
47
|
habtm = JoinTableResolver.build lhs_model, association_name, options
|
46
48
|
|
47
49
|
join_model = Class.new(ActiveRecord::Base) {
|
48
|
-
class << self
|
50
|
+
class << self
|
49
51
|
attr_accessor :left_model
|
50
52
|
attr_accessor :name
|
51
53
|
attr_accessor :table_name_resolver
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Associations
|
3
5
|
# = Active Record Association Collection
|
@@ -60,7 +62,9 @@ module ActiveRecord
|
|
60
62
|
end.values_at(*ids).compact
|
61
63
|
|
62
64
|
if records.size != ids.size
|
63
|
-
|
65
|
+
found_ids = records.map { |record| record.public_send(primary_key) }
|
66
|
+
not_found_ids = ids - found_ids
|
67
|
+
klass.all.raise_record_not_found_exception!(ids, records.size, ids.size, primary_key, not_found_ids)
|
64
68
|
else
|
65
69
|
replace(records)
|
66
70
|
end
|
@@ -69,26 +73,29 @@ module ActiveRecord
|
|
69
73
|
def reset
|
70
74
|
super
|
71
75
|
@target = []
|
76
|
+
@association_ids = nil
|
72
77
|
end
|
73
78
|
|
74
79
|
def find(*args)
|
75
|
-
if
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
80
|
+
if options[:inverse_of] && loaded?
|
81
|
+
args_flatten = args.flatten
|
82
|
+
model = scope.klass
|
83
|
+
|
84
|
+
if args_flatten.blank?
|
85
|
+
error_message = "Couldn't find #{model.name} without an ID"
|
86
|
+
raise RecordNotFound.new(error_message, model.name, model.primary_key, args)
|
87
|
+
end
|
88
|
+
|
89
|
+
result = find_by_scan(*args)
|
90
|
+
|
91
|
+
result_size = Array(result).size
|
92
|
+
if !result || result_size != args_flatten.size
|
93
|
+
scope.raise_record_not_found_exception!(args_flatten, result_size, args_flatten.size)
|
89
94
|
else
|
90
|
-
|
95
|
+
result
|
91
96
|
end
|
97
|
+
else
|
98
|
+
scope.find(*args)
|
92
99
|
end
|
93
100
|
end
|
94
101
|
|
@@ -180,8 +187,6 @@ module ActiveRecord
|
|
180
187
|
# are actually removed from the database, that depends precisely on
|
181
188
|
# +delete_records+. They are in any case removed from the collection.
|
182
189
|
def delete(*records)
|
183
|
-
return if records.empty?
|
184
|
-
records = find(records) if records.any? { |record| record.kind_of?(Integer) || record.kind_of?(String) }
|
185
190
|
delete_or_destroy(records, options[:dependent])
|
186
191
|
end
|
187
192
|
|
@@ -191,8 +196,6 @@ module ActiveRecord
|
|
191
196
|
# Note that this method removes records from the database ignoring the
|
192
197
|
# +:dependent+ option.
|
193
198
|
def destroy(*records)
|
194
|
-
return if records.empty?
|
195
|
-
records = find(records) if records.any? { |record| record.kind_of?(Integer) || record.kind_of?(String) }
|
196
199
|
delete_or_destroy(records, :destroy)
|
197
200
|
end
|
198
201
|
|
@@ -300,18 +303,17 @@ module ActiveRecord
|
|
300
303
|
private
|
301
304
|
|
302
305
|
def find_target
|
303
|
-
|
306
|
+
scope = self.scope
|
307
|
+
return scope.to_a if skip_statement_cache?(scope)
|
304
308
|
|
305
309
|
conn = klass.connection
|
306
|
-
sc = reflection.association_scope_cache(conn, owner) do
|
307
|
-
|
308
|
-
|
309
|
-
target_scope.merge as.scope(self, conn)
|
310
|
-
}
|
310
|
+
sc = reflection.association_scope_cache(conn, owner) do |params|
|
311
|
+
as = AssociationScope.create { params.bind }
|
312
|
+
target_scope.merge!(as.scope(self))
|
311
313
|
end
|
312
314
|
|
313
315
|
binds = AssociationScope.get_bind_values(owner, reflection.chain)
|
314
|
-
sc.execute(binds,
|
316
|
+
sc.execute(binds, conn) do |record|
|
315
317
|
set_inverse_instance(record)
|
316
318
|
end
|
317
319
|
end
|
@@ -357,7 +359,10 @@ module ActiveRecord
|
|
357
359
|
transaction do
|
358
360
|
add_to_target(build_record(attributes)) do |record|
|
359
361
|
yield(record) if block_given?
|
360
|
-
insert_record(record, true, raise) {
|
362
|
+
insert_record(record, true, raise) {
|
363
|
+
@_was_loaded = loaded?
|
364
|
+
@association_ids = nil
|
365
|
+
}
|
361
366
|
end
|
362
367
|
end
|
363
368
|
end
|
@@ -372,11 +377,9 @@ module ActiveRecord
|
|
372
377
|
end
|
373
378
|
end
|
374
379
|
|
375
|
-
def create_scope
|
376
|
-
scope.scope_for_create.stringify_keys
|
377
|
-
end
|
378
|
-
|
379
380
|
def delete_or_destroy(records, method)
|
381
|
+
return if records.empty?
|
382
|
+
records = find(records) if records.any? { |record| record.kind_of?(Integer) || record.kind_of?(String) }
|
380
383
|
records = records.flatten
|
381
384
|
records.each { |record| raise_on_type_mismatch!(record) }
|
382
385
|
existing_records = records.reject(&:new_record?)
|
@@ -430,7 +433,12 @@ module ActiveRecord
|
|
430
433
|
records.each do |record|
|
431
434
|
raise_on_type_mismatch!(record)
|
432
435
|
add_to_target(record) do
|
433
|
-
|
436
|
+
unless owner.new_record?
|
437
|
+
result &&= insert_record(record, true, raise) {
|
438
|
+
@_was_loaded = loaded?
|
439
|
+
@association_ids = nil
|
440
|
+
}
|
441
|
+
end
|
434
442
|
end
|
435
443
|
end
|
436
444
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Associations
|
3
5
|
# Association proxies in Active Record are middlemen between the object that
|
@@ -133,8 +135,9 @@ module ActiveRecord
|
|
133
135
|
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
134
136
|
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
135
137
|
# # ]
|
136
|
-
def find(*args
|
137
|
-
|
138
|
+
def find(*args)
|
139
|
+
return super if block_given?
|
140
|
+
@association.find(*args)
|
138
141
|
end
|
139
142
|
|
140
143
|
##
|
@@ -746,10 +749,6 @@ module ActiveRecord
|
|
746
749
|
# # ]
|
747
750
|
|
748
751
|
#--
|
749
|
-
def uniq
|
750
|
-
load_target.uniq
|
751
|
-
end
|
752
|
-
|
753
752
|
def calculate(operation, column_name)
|
754
753
|
null_scope? ? scope.calculate(operation, column_name) : super
|
755
754
|
end
|
@@ -989,6 +988,12 @@ module ActiveRecord
|
|
989
988
|
load_target == other
|
990
989
|
end
|
991
990
|
|
991
|
+
##
|
992
|
+
# :method: to_ary
|
993
|
+
#
|
994
|
+
# :call-seq:
|
995
|
+
# to_ary()
|
996
|
+
#
|
992
997
|
# Returns a new array of objects from the collection. If the collection
|
993
998
|
# hasn't been loaded, it fetches the records from the database.
|
994
999
|
#
|
@@ -1022,10 +1027,6 @@ module ActiveRecord
|
|
1022
1027
|
# # #<Pet id: 5, name: "Brain", person_id: 1>,
|
1023
1028
|
# # #<Pet id: 6, name: "Boss", person_id: 1>
|
1024
1029
|
# # ]
|
1025
|
-
def to_ary
|
1026
|
-
load_target.dup
|
1027
|
-
end
|
1028
|
-
alias_method :to_a, :to_ary
|
1029
1030
|
|
1030
1031
|
def records # :nodoc:
|
1031
1032
|
load_target
|
@@ -1073,7 +1074,6 @@ module ActiveRecord
|
|
1073
1074
|
end
|
1074
1075
|
|
1075
1076
|
# Reloads the collection from the database. Returns +self+.
|
1076
|
-
# Equivalent to <tt>collection(true)</tt>.
|
1077
1077
|
#
|
1078
1078
|
# class Person < ActiveRecord::Base
|
1079
1079
|
# has_many :pets
|
@@ -1087,9 +1087,6 @@ module ActiveRecord
|
|
1087
1087
|
#
|
1088
1088
|
# person.pets.reload # fetches pets from the database
|
1089
1089
|
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
1090
|
-
#
|
1091
|
-
# person.pets(true) # fetches pets from the database
|
1092
|
-
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
|
1093
1090
|
def reload
|
1094
1091
|
proxy_association.reload
|
1095
1092
|
reset_scope
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
|
-
# = Active Record Has Many Association
|
3
4
|
module Associations
|
5
|
+
# = Active Record Has Many Association
|
4
6
|
# This is the proxy that handles a has many association.
|
5
7
|
#
|
6
8
|
# If the association has a <tt>:through</tt> option further specialization
|
@@ -61,7 +63,7 @@ module ActiveRecord
|
|
61
63
|
count = if reflection.has_cached_counter?
|
62
64
|
owner._read_attribute(reflection.counter_cache_column).to_i
|
63
65
|
else
|
64
|
-
scope.count
|
66
|
+
scope.count
|
65
67
|
end
|
66
68
|
|
67
69
|
# If there's nothing in the database and @target has no new records
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
|
-
# = Active Record Has Many Through Association
|
3
4
|
module Associations
|
5
|
+
# = Active Record Has Many Through Association
|
4
6
|
class HasManyThroughAssociation < HasManyAssociation #:nodoc:
|
5
7
|
include ThroughAssociation
|
6
8
|
|
@@ -152,7 +154,7 @@ module ActiveRecord
|
|
152
154
|
stmt.from scope.klass.arel_table
|
153
155
|
stmt.wheres = arel.constraints
|
154
156
|
|
155
|
-
count = scope.klass.connection.delete(stmt, "SQL"
|
157
|
+
count = scope.klass.connection.delete(stmt, "SQL")
|
156
158
|
end
|
157
159
|
when :nullify
|
158
160
|
count = scope.update_all(source_reflection.foreign_key => nil)
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
|
-
# = Active Record Has One Through Association
|
3
4
|
module Associations
|
5
|
+
# = Active Record Has One Through Association
|
4
6
|
class HasOneThroughAssociation < HasOneAssociation #:nodoc:
|
5
7
|
include ThroughAssociation
|
6
8
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Associations
|
3
5
|
class JoinDependency # :nodoc:
|
@@ -33,20 +35,14 @@ module ActiveRecord
|
|
33
35
|
end
|
34
36
|
|
35
37
|
Table = Struct.new(:node, :columns) do # :nodoc:
|
36
|
-
def table
|
37
|
-
Arel::Nodes::TableAlias.new node.table, node.aliased_table_name
|
38
|
-
end
|
39
|
-
|
40
38
|
def column_aliases
|
41
|
-
t = table
|
39
|
+
t = node.table
|
42
40
|
columns.map { |column| t[column.name].as Arel.sql column.alias }
|
43
41
|
end
|
44
42
|
end
|
45
43
|
Column = Struct.new(:name, :alias)
|
46
44
|
end
|
47
45
|
|
48
|
-
attr_reader :alias_tracker, :base_klass, :join_root
|
49
|
-
|
50
46
|
def self.make_tree(associations)
|
51
47
|
hash = {}
|
52
48
|
walk_tree associations, hash
|
@@ -92,11 +88,11 @@ module ActiveRecord
|
|
92
88
|
# associations # => [:appointments]
|
93
89
|
# joins # => []
|
94
90
|
#
|
95
|
-
def initialize(base, associations,
|
96
|
-
@alias_tracker =
|
91
|
+
def initialize(base, table, associations, alias_tracker, eager_loading: true)
|
92
|
+
@alias_tracker = alias_tracker
|
97
93
|
@eager_loading = eager_loading
|
98
94
|
tree = self.class.make_tree associations
|
99
|
-
@join_root = JoinBase.new
|
95
|
+
@join_root = JoinBase.new(base, table, build(tree, base))
|
100
96
|
@join_root.children.each { |child| construct_tables! @join_root, child }
|
101
97
|
end
|
102
98
|
|
@@ -104,22 +100,17 @@ module ActiveRecord
|
|
104
100
|
join_root.drop(1).map!(&:reflection)
|
105
101
|
end
|
106
102
|
|
107
|
-
def join_constraints(
|
103
|
+
def join_constraints(joins_to_add, join_type)
|
108
104
|
joins = join_root.children.flat_map { |child|
|
109
|
-
|
110
|
-
if join_type == Arel::Nodes::OuterJoin
|
111
|
-
make_left_outer_joins join_root, child
|
112
|
-
else
|
113
|
-
make_inner_joins join_root, child
|
114
|
-
end
|
105
|
+
make_join_constraints(join_root, child, join_type)
|
115
106
|
}
|
116
107
|
|
117
|
-
joins.concat
|
108
|
+
joins.concat joins_to_add.flat_map { |oj|
|
118
109
|
if join_root.match? oj.join_root
|
119
110
|
walk join_root, oj.join_root
|
120
111
|
else
|
121
112
|
oj.join_root.children.flat_map { |child|
|
122
|
-
|
113
|
+
make_join_constraints(oj.join_root, child, join_type)
|
123
114
|
}
|
124
115
|
end
|
125
116
|
}
|
@@ -165,6 +156,9 @@ module ActiveRecord
|
|
165
156
|
parents.values
|
166
157
|
end
|
167
158
|
|
159
|
+
protected
|
160
|
+
attr_reader :alias_tracker, :base_klass, :join_root
|
161
|
+
|
168
162
|
private
|
169
163
|
|
170
164
|
def make_constraints(parent, child, tables, join_type)
|
@@ -175,27 +169,15 @@ module ActiveRecord
|
|
175
169
|
end
|
176
170
|
|
177
171
|
def make_outer_joins(parent, child)
|
178
|
-
tables = table_aliases_for(parent, child)
|
179
|
-
join_type = Arel::Nodes::OuterJoin
|
180
|
-
info = make_constraints parent, child, tables, join_type
|
181
|
-
|
182
|
-
[info] + child.children.flat_map { |c| make_outer_joins(child, c) }
|
183
|
-
end
|
184
|
-
|
185
|
-
def make_left_outer_joins(parent, child)
|
186
|
-
tables = child.tables
|
187
172
|
join_type = Arel::Nodes::OuterJoin
|
188
|
-
|
189
|
-
|
190
|
-
[info] + child.children.flat_map { |c| make_left_outer_joins(child, c) }
|
173
|
+
make_join_constraints(parent, child, join_type, true)
|
191
174
|
end
|
192
175
|
|
193
|
-
def
|
194
|
-
tables
|
195
|
-
|
196
|
-
info = make_constraints parent, child, tables, join_type
|
176
|
+
def make_join_constraints(parent, child, join_type, aliasing = false)
|
177
|
+
tables = aliasing ? table_aliases_for(parent, child) : child.tables
|
178
|
+
joins = make_constraints(parent, child, tables, join_type)
|
197
179
|
|
198
|
-
|
180
|
+
joins.concat child.children.flat_map { |c| make_join_constraints(child, c, join_type, aliasing) }
|
199
181
|
end
|
200
182
|
|
201
183
|
def table_aliases_for(parent, node)
|
@@ -215,8 +197,7 @@ module ActiveRecord
|
|
215
197
|
|
216
198
|
def table_alias_for(reflection, parent, join)
|
217
199
|
name = "#{reflection.plural_name}_#{parent.table_name}"
|
218
|
-
|
219
|
-
name
|
200
|
+
join ? "#{name}_join" : name
|
220
201
|
end
|
221
202
|
|
222
203
|
def walk(left, right)
|
@@ -244,7 +225,7 @@ module ActiveRecord
|
|
244
225
|
raise EagerLoadPolymorphicError.new(reflection)
|
245
226
|
end
|
246
227
|
|
247
|
-
JoinAssociation.new
|
228
|
+
JoinAssociation.new(reflection, build(right, reflection.klass), alias_tracker)
|
248
229
|
end.compact
|
249
230
|
end
|
250
231
|
|
@@ -276,7 +257,8 @@ module ActiveRecord
|
|
276
257
|
else
|
277
258
|
model = construct_model(ar_parent, node, row, model_cache, id, aliases)
|
278
259
|
|
279
|
-
if node.reflection.
|
260
|
+
if node.reflection.scope &&
|
261
|
+
node.reflection.scope_for(node.base_klass.unscoped).readonly_value
|
280
262
|
model.readonly!
|
281
263
|
end
|
282
264
|
|