activerecord 5.2.6 → 6.1.3.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1038 -571
- data/MIT-LICENSE +3 -1
- data/README.rdoc +7 -5
- data/examples/performance.rb +1 -1
- data/lib/active_record.rb +13 -12
- data/lib/active_record/aggregations.rb +9 -8
- data/lib/active_record/association_relation.rb +30 -10
- data/lib/active_record/associations.rb +137 -25
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +95 -42
- data/lib/active_record/associations/association_scope.rb +23 -21
- data/lib/active_record/associations/belongs_to_association.rb +54 -46
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -6
- data/lib/active_record/associations/builder/association.rb +45 -22
- data/lib/active_record/associations/builder/belongs_to.rb +29 -59
- data/lib/active_record/associations/builder/collection_association.rb +8 -17
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
- data/lib/active_record/associations/builder/has_many.rb +8 -2
- data/lib/active_record/associations/builder/has_one.rb +33 -2
- data/lib/active_record/associations/builder/singular_association.rb +3 -1
- data/lib/active_record/associations/collection_association.rb +31 -29
- data/lib/active_record/associations/collection_proxy.rb +25 -21
- data/lib/active_record/associations/foreign_association.rb +20 -0
- data/lib/active_record/associations/has_many_association.rb +26 -13
- data/lib/active_record/associations/has_many_through_association.rb +24 -18
- data/lib/active_record/associations/has_one_association.rb +43 -31
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency.rb +91 -60
- data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
- data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
- data/lib/active_record/associations/preloader.rb +47 -34
- data/lib/active_record/associations/preloader/association.rb +71 -43
- data/lib/active_record/associations/preloader/through_association.rb +49 -40
- data/lib/active_record/associations/singular_association.rb +3 -17
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_assignment.rb +17 -19
- data/lib/active_record/attribute_methods.rb +81 -143
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
- data/lib/active_record/attribute_methods/dirty.rb +101 -40
- data/lib/active_record/attribute_methods/primary_key.rb +20 -25
- data/lib/active_record/attribute_methods/query.rb +4 -8
- data/lib/active_record/attribute_methods/read.rb +14 -56
- data/lib/active_record/attribute_methods/serialization.rb +12 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +18 -34
- data/lib/active_record/attributes.rb +46 -9
- data/lib/active_record/autosave_association.rb +57 -42
- data/lib/active_record/base.rb +4 -17
- data/lib/active_record/callbacks.rb +158 -43
- data/lib/active_record/coders/yaml_column.rb +1 -2
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +272 -130
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -14
- data/lib/active_record/connection_adapters/abstract/quoting.rb +98 -47
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -90
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +385 -144
- data/lib/active_record/connection_adapters/abstract/transaction.rb +155 -68
- data/lib/active_record/connection_adapters/abstract_adapter.rb +228 -98
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
- data/lib/active_record/connection_adapters/column.rb +30 -12
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +86 -32
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +59 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +18 -7
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
- data/lib/active_record/connection_adapters/pool_config.rb +73 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +38 -54
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -120
- data/lib/active_record/connection_adapters/schema_cache.rb +127 -21
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +19 -6
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +174 -186
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +293 -33
- data/lib/active_record/core.rb +323 -97
- data/lib/active_record/counter_cache.rb +8 -30
- data/lib/active_record/database_configurations.rb +272 -0
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +80 -0
- data/lib/active_record/database_configurations/hash_config.rb +96 -0
- data/lib/active_record/database_configurations/url_config.rb +53 -0
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +3 -4
- data/lib/active_record/enum.rb +111 -37
- data/lib/active_record/errors.rb +62 -19
- data/lib/active_record/explain.rb +10 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- data/lib/active_record/fixture_set/model_metadata.rb +32 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +200 -481
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +53 -24
- data/lib/active_record/insert_all.rb +208 -0
- data/lib/active_record/integration.rb +67 -17
- data/lib/active_record/internal_metadata.rb +26 -9
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +37 -23
- data/lib/active_record/locking/pessimistic.rb +9 -5
- data/lib/active_record/log_subscriber.rb +35 -35
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/migration.rb +206 -157
- data/lib/active_record/migration/command_recorder.rb +96 -44
- data/lib/active_record/migration/compatibility.rb +142 -64
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +148 -22
- data/lib/active_record/nested_attributes.rb +4 -7
- data/lib/active_record/no_touching.rb +8 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +267 -59
- data/lib/active_record/query_cache.rb +21 -4
- data/lib/active_record/querying.rb +40 -23
- data/lib/active_record/railtie.rb +115 -58
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +408 -78
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +109 -93
- data/lib/active_record/relation.rb +374 -104
- data/lib/active_record/relation/batches.rb +44 -35
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/calculations.rb +153 -90
- data/lib/active_record/relation/delegation.rb +35 -50
- data/lib/active_record/relation/finder_methods.rb +64 -39
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +32 -40
- data/lib/active_record/relation/predicate_builder.rb +62 -45
- data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +475 -186
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +9 -9
- data/lib/active_record/relation/where_clause.rb +111 -61
- data/lib/active_record/result.rb +64 -38
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +22 -41
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +54 -9
- data/lib/active_record/schema_migration.rb +7 -9
- data/lib/active_record/scoping.rb +8 -9
- data/lib/active_record/scoping/default.rb +4 -6
- data/lib/active_record/scoping/named.rb +17 -24
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +49 -6
- data/lib/active_record/store.rb +88 -9
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +42 -43
- data/lib/active_record/tasks/database_tasks.rb +277 -81
- data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
- data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
- data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +246 -0
- data/lib/active_record/timestamp.rb +43 -32
- data/lib/active_record/touch_later.rb +23 -22
- data/lib/active_record/transactions.rb +62 -118
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type.rb +10 -5
- data/lib/active_record/type/adapter_specific_registry.rb +3 -13
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +6 -3
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type_caster/connection.rb +15 -15
- data/lib/active_record/type_caster/map.rb +8 -8
- data/lib/active_record/validations.rb +4 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +38 -30
- data/lib/arel.rb +54 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +41 -0
- data/lib/arel/collectors/bind.rb +29 -0
- data/lib/arel/collectors/composite.rb +39 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +27 -0
- data/lib/arel/collectors/substitute_binds.rb +35 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes.rb +70 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +126 -0
- data/lib/arel/nodes/bind_param.rb +44 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +62 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +15 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +11 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +15 -0
- data/lib/arel/nodes/infix_operation.rb +92 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +51 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +19 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +31 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +250 -0
- data/lib/arel/select_manager.rb +270 -0
- data/lib/arel/table.rb +118 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors.rb +13 -0
- data/lib/arel/visitors/dot.rb +308 -0
- data/lib/arel/visitors/mysql.rb +93 -0
- data/lib/arel/visitors/postgresql.rb +120 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +899 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration.rb +19 -2
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
- data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +119 -34
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/collection_cache_key.rb +0 -53
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
- data/lib/active_record/relation/where_clause_factory.rb +0 -34
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
Copyright (c) 2004-
|
1
|
+
Copyright (c) 2004-2020 David Heinemeier Hansson
|
2
|
+
|
3
|
+
Arel originally copyright (c) 2007-2016 Nick Kallen, Bryan Helmkamp, Emilio Tagua, Aaron Patterson
|
2
4
|
|
3
5
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
6
|
a copy of this software and associated documentation files (the
|
data/README.rdoc
CHANGED
@@ -13,6 +13,8 @@ columns. Although these mappings can be defined explicitly, it's recommended
|
|
13
13
|
to follow naming conventions, especially when getting started with the
|
14
14
|
library.
|
15
15
|
|
16
|
+
You can read more about Active Record in the {Active Record Basics}[https://edgeguides.rubyonrails.org/active_record_basics.html] guide.
|
17
|
+
|
16
18
|
A short rundown of some of the major features:
|
17
19
|
|
18
20
|
* Automated mapping between classes and tables, attributes and columns.
|
@@ -130,7 +132,7 @@ This would also define the following accessors: <tt>Product#name</tt> and
|
|
130
132
|
SQLite3[link:classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html].
|
131
133
|
|
132
134
|
|
133
|
-
* Logging support for Log4r[https://github.com/colbygk/log4r] and Logger[
|
135
|
+
* Logging support for Log4r[https://github.com/colbygk/log4r] and Logger[https://ruby-doc.org/stdlib/libdoc/logger/rdoc/].
|
134
136
|
|
135
137
|
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)
|
136
138
|
ActiveRecord::Base.logger = Log4r::Logger.new('Application Log')
|
@@ -138,7 +140,7 @@ This would also define the following accessors: <tt>Product#name</tt> and
|
|
138
140
|
|
139
141
|
* Database agnostic schema management with Migrations.
|
140
142
|
|
141
|
-
class AddSystemSettings < ActiveRecord::Migration[
|
143
|
+
class AddSystemSettings < ActiveRecord::Migration[6.0]
|
142
144
|
def up
|
143
145
|
create_table :system_settings do |t|
|
144
146
|
t.string :name
|
@@ -192,7 +194,7 @@ The latest version of Active Record can be installed with RubyGems:
|
|
192
194
|
|
193
195
|
Source code can be downloaded as part of the Rails project on GitHub:
|
194
196
|
|
195
|
-
* https://github.com/rails/rails/tree/
|
197
|
+
* https://github.com/rails/rails/tree/main/activerecord
|
196
198
|
|
197
199
|
|
198
200
|
== License
|
@@ -206,7 +208,7 @@ Active Record is released under the MIT license:
|
|
206
208
|
|
207
209
|
API documentation is at:
|
208
210
|
|
209
|
-
*
|
211
|
+
* https://api.rubyonrails.org
|
210
212
|
|
211
213
|
Bug reports for the Ruby on Rails project can be filed here:
|
212
214
|
|
@@ -214,4 +216,4 @@ Bug reports for the Ruby on Rails project can be filed here:
|
|
214
216
|
|
215
217
|
Feature requests should be discussed on the rails-core mailing list here:
|
216
218
|
|
217
|
-
* https://
|
219
|
+
* https://discuss.rubyonrails.org/c/rubyonrails-core
|
data/examples/performance.rb
CHANGED
data/lib/active_record.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2004-
|
4
|
+
# Copyright (c) 2004-2020 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -31,6 +31,7 @@ require "yaml"
|
|
31
31
|
|
32
32
|
require "active_record/version"
|
33
33
|
require "active_model/attribute_set"
|
34
|
+
require "active_record/errors"
|
34
35
|
|
35
36
|
module ActiveRecord
|
36
37
|
extend ActiveSupport::Autoload
|
@@ -41,6 +42,7 @@ module ActiveRecord
|
|
41
42
|
autoload :ConnectionHandling
|
42
43
|
autoload :CounterCache
|
43
44
|
autoload :DynamicMatchers
|
45
|
+
autoload :DelegatedType
|
44
46
|
autoload :Enum
|
45
47
|
autoload :InternalMetadata
|
46
48
|
autoload :Explain
|
@@ -55,7 +57,6 @@ module ActiveRecord
|
|
55
57
|
autoload :Persistence
|
56
58
|
autoload :QueryCache
|
57
59
|
autoload :Querying
|
58
|
-
autoload :CollectionCacheKey
|
59
60
|
autoload :ReadonlyAttributes
|
60
61
|
autoload :RecordInvalid, "active_record/validations"
|
61
62
|
autoload :Reflection
|
@@ -68,17 +69,17 @@ module ActiveRecord
|
|
68
69
|
autoload :Serialization
|
69
70
|
autoload :StatementCache
|
70
71
|
autoload :Store
|
72
|
+
autoload :SignedId
|
71
73
|
autoload :Suppressor
|
72
74
|
autoload :Timestamp
|
73
75
|
autoload :Transactions
|
74
76
|
autoload :Translation
|
75
77
|
autoload :Validations
|
76
78
|
autoload :SecureToken
|
79
|
+
autoload :DestroyAssociationAsyncJob
|
77
80
|
|
78
81
|
eager_autoload do
|
79
|
-
autoload :
|
80
|
-
autoload :ConnectionNotEstablished, "active_record/errors"
|
81
|
-
autoload :ConnectionAdapters, "active_record/connection_adapters/abstract_adapter"
|
82
|
+
autoload :ConnectionAdapters
|
82
83
|
|
83
84
|
autoload :Aggregations
|
84
85
|
autoload :Associations
|
@@ -136,21 +137,19 @@ module ActiveRecord
|
|
136
137
|
end
|
137
138
|
end
|
138
139
|
|
139
|
-
module
|
140
|
+
module Scoping
|
140
141
|
extend ActiveSupport::Autoload
|
141
142
|
|
142
143
|
eager_autoload do
|
143
|
-
autoload :
|
144
|
+
autoload :Named
|
145
|
+
autoload :Default
|
144
146
|
end
|
145
147
|
end
|
146
148
|
|
147
|
-
module
|
149
|
+
module Middleware
|
148
150
|
extend ActiveSupport::Autoload
|
149
151
|
|
150
|
-
|
151
|
-
autoload :Named
|
152
|
-
autoload :Default
|
153
|
-
end
|
152
|
+
autoload :DatabaseSelector, "active_record/middleware/database_selector"
|
154
153
|
end
|
155
154
|
|
156
155
|
module Tasks
|
@@ -163,6 +162,7 @@ module ActiveRecord
|
|
163
162
|
"active_record/tasks/postgresql_database_tasks"
|
164
163
|
end
|
165
164
|
|
165
|
+
autoload :TestDatabases, "active_record/test_databases"
|
166
166
|
autoload :TestFixtures, "active_record/fixtures"
|
167
167
|
|
168
168
|
def self.eager_load!
|
@@ -186,3 +186,4 @@ end
|
|
186
186
|
YAML.load_tags["!ruby/object:ActiveRecord::AttributeSet"] = "ActiveModel::AttributeSet"
|
187
187
|
YAML.load_tags["!ruby/object:ActiveRecord::Attribute::FromDatabase"] = "ActiveModel::Attribute::FromDatabase"
|
188
188
|
YAML.load_tags["!ruby/object:ActiveRecord::LazyAttributeHash"] = "ActiveModel::LazyAttributeHash"
|
189
|
+
YAML.load_tags["!ruby/object:ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::MysqlString"] = "ActiveRecord::Type::String"
|
@@ -3,8 +3,6 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
# See ActiveRecord::Aggregations::ClassMethods for documentation
|
5
5
|
module Aggregations
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
6
|
def initialize_dup(*) # :nodoc:
|
9
7
|
@aggregation_cache = {}
|
10
8
|
super
|
@@ -16,7 +14,6 @@ module ActiveRecord
|
|
16
14
|
end
|
17
15
|
|
18
16
|
private
|
19
|
-
|
20
17
|
def clear_aggregation_cache
|
21
18
|
@aggregation_cache.clear if persisted?
|
22
19
|
end
|
@@ -144,7 +141,7 @@ module ActiveRecord
|
|
144
141
|
# converted to an instance of value class if necessary.
|
145
142
|
#
|
146
143
|
# For example, the +NetworkResource+ model has +network_address+ and +cidr_range+ attributes that should be
|
147
|
-
# aggregated using the +NetAddr::CIDR+ value class (
|
144
|
+
# aggregated using the +NetAddr::CIDR+ value class (https://www.rubydoc.info/gems/netaddr/1.5.0/NetAddr/CIDR).
|
148
145
|
# The constructor for the value class is called +create+ and it expects a CIDR address string as a parameter.
|
149
146
|
# New values can be assigned to the value object using either another +NetAddr::CIDR+ object, a string
|
150
147
|
# or an array. The <tt>:constructor</tt> and <tt>:converter</tt> options can be used to meet
|
@@ -225,6 +222,10 @@ module ActiveRecord
|
|
225
222
|
def composed_of(part_id, options = {})
|
226
223
|
options.assert_valid_keys(:class_name, :mapping, :allow_nil, :constructor, :converter)
|
227
224
|
|
225
|
+
unless self < Aggregations
|
226
|
+
include Aggregations
|
227
|
+
end
|
228
|
+
|
228
229
|
name = part_id.id2name
|
229
230
|
class_name = options[:class_name] || name.camelize
|
230
231
|
mapping = options[:mapping] || [ name, name ]
|
@@ -243,8 +244,8 @@ module ActiveRecord
|
|
243
244
|
private
|
244
245
|
def reader_method(name, class_name, mapping, allow_nil, constructor)
|
245
246
|
define_method(name) do
|
246
|
-
if @aggregation_cache[name].nil? && (!allow_nil || mapping.any? { |key, _| !
|
247
|
-
attrs = mapping.collect { |key, _|
|
247
|
+
if @aggregation_cache[name].nil? && (!allow_nil || mapping.any? { |key, _| !read_attribute(key).nil? })
|
248
|
+
attrs = mapping.collect { |key, _| read_attribute(key) }
|
248
249
|
object = constructor.respond_to?(:call) ?
|
249
250
|
constructor.call(*attrs) :
|
250
251
|
class_name.constantize.send(constructor, *attrs)
|
@@ -270,10 +271,10 @@ module ActiveRecord
|
|
270
271
|
end
|
271
272
|
|
272
273
|
if part.nil? && allow_nil
|
273
|
-
mapping.each { |key, _|
|
274
|
+
mapping.each { |key, _| write_attribute(key, nil) }
|
274
275
|
@aggregation_cache[name] = nil
|
275
276
|
else
|
276
|
-
mapping.each { |key, value|
|
277
|
+
mapping.each { |key, value| write_attribute(key, part.send(value)) }
|
277
278
|
@aggregation_cache[name] = part.freeze
|
278
279
|
end
|
279
280
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
|
-
class AssociationRelation < Relation
|
5
|
-
def initialize(klass, association)
|
4
|
+
class AssociationRelation < Relation # :nodoc:
|
5
|
+
def initialize(klass, association, **)
|
6
6
|
super(klass)
|
7
7
|
@association = association
|
8
8
|
end
|
@@ -15,20 +15,40 @@ module ActiveRecord
|
|
15
15
|
other == records
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
%w(insert insert_all insert! insert_all! upsert upsert_all).each do |method|
|
19
|
+
class_eval <<~RUBY
|
20
|
+
def #{method}(attributes, **kwargs)
|
21
|
+
if @association.reflection.through_reflection?
|
22
|
+
raise ArgumentError, "Bulk insert or upsert is currently not supported for has_many through association"
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
+
scoping { klass.#{method}(attributes, **kwargs) }
|
26
|
+
end
|
27
|
+
RUBY
|
25
28
|
end
|
26
29
|
|
27
|
-
def
|
28
|
-
|
30
|
+
def build(attributes = nil, &block)
|
31
|
+
if attributes.is_a?(Array)
|
32
|
+
attributes.collect { |attr| build(attr, &block) }
|
33
|
+
else
|
34
|
+
block = current_scope_restoring_block(&block)
|
35
|
+
scoping { _new(attributes, &block) }
|
36
|
+
end
|
29
37
|
end
|
38
|
+
alias new build
|
30
39
|
|
31
40
|
private
|
41
|
+
def _new(attributes, &block)
|
42
|
+
@association.build(attributes, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def _create(attributes, &block)
|
46
|
+
@association.create(attributes, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def _create!(attributes, &block)
|
50
|
+
@association.create!(attributes, &block)
|
51
|
+
end
|
32
52
|
|
33
53
|
def exec_queries
|
34
54
|
super do |record|
|
@@ -2,38 +2,116 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/enumerable"
|
4
4
|
require "active_support/core_ext/string/conversions"
|
5
|
-
require "active_support/core_ext/module/remove_method"
|
6
|
-
require "active_record/errors"
|
7
5
|
|
8
6
|
module ActiveRecord
|
9
7
|
class AssociationNotFoundError < ConfigurationError #:nodoc:
|
8
|
+
attr_reader :record, :association_name
|
10
9
|
def initialize(record = nil, association_name = nil)
|
10
|
+
@record = record
|
11
|
+
@association_name = association_name
|
11
12
|
if record && association_name
|
12
13
|
super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
|
13
14
|
else
|
14
15
|
super("Association was not found.")
|
15
16
|
end
|
16
17
|
end
|
18
|
+
|
19
|
+
class Correction
|
20
|
+
def initialize(error)
|
21
|
+
@error = error
|
22
|
+
end
|
23
|
+
|
24
|
+
def corrections
|
25
|
+
if @error.association_name
|
26
|
+
maybe_these = @error.record.class.reflections.keys
|
27
|
+
|
28
|
+
maybe_these.sort_by { |n|
|
29
|
+
DidYouMean::Jaro.distance(@error.association_name.to_s, n)
|
30
|
+
}.reverse.first(4)
|
31
|
+
else
|
32
|
+
[]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# We may not have DYM, and DYM might not let us register error handlers
|
38
|
+
if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
|
39
|
+
DidYouMean.correct_error(self, Correction)
|
40
|
+
end
|
17
41
|
end
|
18
42
|
|
19
43
|
class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
|
44
|
+
attr_reader :reflection, :associated_class
|
20
45
|
def initialize(reflection = nil, associated_class = nil)
|
21
46
|
if reflection
|
47
|
+
@reflection = reflection
|
48
|
+
@associated_class = associated_class.nil? ? reflection.klass : associated_class
|
22
49
|
super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
|
23
50
|
else
|
24
51
|
super("Could not find the inverse association.")
|
25
52
|
end
|
26
53
|
end
|
54
|
+
|
55
|
+
class Correction
|
56
|
+
def initialize(error)
|
57
|
+
@error = error
|
58
|
+
end
|
59
|
+
|
60
|
+
def corrections
|
61
|
+
if @error.reflection && @error.associated_class
|
62
|
+
maybe_these = @error.associated_class.reflections.keys
|
63
|
+
|
64
|
+
maybe_these.sort_by { |n|
|
65
|
+
DidYouMean::Jaro.distance(@error.reflection.options[:inverse_of].to_s, n)
|
66
|
+
}.reverse.first(4)
|
67
|
+
else
|
68
|
+
[]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# We may not have DYM, and DYM might not let us register error handlers
|
74
|
+
if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
|
75
|
+
DidYouMean.correct_error(self, Correction)
|
76
|
+
end
|
27
77
|
end
|
28
78
|
|
29
79
|
class HasManyThroughAssociationNotFoundError < ActiveRecordError #:nodoc:
|
30
|
-
|
31
|
-
|
32
|
-
|
80
|
+
attr_reader :owner_class, :reflection
|
81
|
+
|
82
|
+
def initialize(owner_class = nil, reflection = nil)
|
83
|
+
if owner_class && reflection
|
84
|
+
@owner_class = owner_class
|
85
|
+
@reflection = reflection
|
86
|
+
super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class.name}")
|
33
87
|
else
|
34
88
|
super("Could not find the association.")
|
35
89
|
end
|
36
90
|
end
|
91
|
+
|
92
|
+
class Correction
|
93
|
+
def initialize(error)
|
94
|
+
@error = error
|
95
|
+
end
|
96
|
+
|
97
|
+
def corrections
|
98
|
+
if @error.reflection && @error.owner_class
|
99
|
+
maybe_these = @error.owner_class.reflections.keys
|
100
|
+
maybe_these -= [@error.reflection.name.to_s] # remove failing reflection
|
101
|
+
|
102
|
+
maybe_these.sort_by { |n|
|
103
|
+
DidYouMean::Jaro.distance(@error.reflection.options[:through].to_s, n)
|
104
|
+
}.reverse.first(4)
|
105
|
+
else
|
106
|
+
[]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# We may not have DYM, and DYM might not let us register error handlers
|
112
|
+
if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
|
113
|
+
DidYouMean.correct_error(self, Correction)
|
114
|
+
end
|
37
115
|
end
|
38
116
|
|
39
117
|
class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError #:nodoc:
|
@@ -92,7 +170,7 @@ module ActiveRecord
|
|
92
170
|
through_reflection = reflection.through_reflection
|
93
171
|
source_reflection_names = reflection.source_reflection_names
|
94
172
|
source_associations = reflection.through_reflection.klass._reflections.keys
|
95
|
-
super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(two_words_connector: ' or ', last_word_connector: ', or '
|
173
|
+
super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')}?")
|
96
174
|
else
|
97
175
|
super("Could not find the source association(s).")
|
98
176
|
end
|
@@ -292,13 +370,13 @@ module ActiveRecord
|
|
292
370
|
#
|
293
371
|
# The project class now has the following methods (and more) to ease the traversal and
|
294
372
|
# manipulation of its relationships:
|
295
|
-
# * <tt>Project#portfolio
|
296
|
-
# * <tt>Project#project_manager
|
297
|
-
# * <tt>Project#milestones.empty
|
298
|
-
# <tt>Project#milestones.delete(milestone)
|
299
|
-
# <tt>Project#milestones.build
|
300
|
-
# * <tt>Project#categories.empty
|
301
|
-
# <tt>Project#categories.delete(category1)
|
373
|
+
# * <tt>Project#portfolio</tt>, <tt>Project#portfolio=(portfolio)</tt>, <tt>Project#reload_portfolio</tt>
|
374
|
+
# * <tt>Project#project_manager</tt>, <tt>Project#project_manager=(project_manager)</tt>, <tt>Project#reload_project_manager</tt>
|
375
|
+
# * <tt>Project#milestones.empty?</tt>, <tt>Project#milestones.size</tt>, <tt>Project#milestones</tt>, <tt>Project#milestones<<(milestone)</tt>,
|
376
|
+
# <tt>Project#milestones.delete(milestone)</tt>, <tt>Project#milestones.destroy(milestone)</tt>, <tt>Project#milestones.find(milestone_id)</tt>,
|
377
|
+
# <tt>Project#milestones.build</tt>, <tt>Project#milestones.create</tt>
|
378
|
+
# * <tt>Project#categories.empty?</tt>, <tt>Project#categories.size</tt>, <tt>Project#categories</tt>, <tt>Project#categories<<(category1)</tt>,
|
379
|
+
# <tt>Project#categories.delete(category1)</tt>, <tt>Project#categories.destroy(category1)</tt>
|
302
380
|
#
|
303
381
|
# === A word of warning
|
304
382
|
#
|
@@ -702,9 +780,9 @@ module ActiveRecord
|
|
702
780
|
# inverse detection only works on #has_many, #has_one, and
|
703
781
|
# #belongs_to associations.
|
704
782
|
#
|
705
|
-
#
|
706
|
-
#
|
707
|
-
#
|
783
|
+
# <tt>:foreign_key</tt> and <tt>:through</tt> options on the associations,
|
784
|
+
# or a custom scope, will also prevent the association's inverse
|
785
|
+
# from being found automatically.
|
708
786
|
#
|
709
787
|
# The automatic guessing of the inverse association uses a heuristic based
|
710
788
|
# on the name of the class, so it may not work for all associations,
|
@@ -1291,10 +1369,15 @@ module ActiveRecord
|
|
1291
1369
|
# similar callbacks may affect the <tt>:dependent</tt> behavior, and the
|
1292
1370
|
# <tt>:dependent</tt> behavior may affect other callbacks.
|
1293
1371
|
#
|
1372
|
+
# * <tt>nil</tt> do nothing (default).
|
1294
1373
|
# * <tt>:destroy</tt> causes all the associated objects to also be destroyed.
|
1374
|
+
# * <tt>:destroy_async</tt> destroys all the associated objects in a background job. <b>WARNING:</b> Do not use
|
1375
|
+
# this option if the association is backed by foreign key constraints in your database. The foreign key
|
1376
|
+
# constraint actions will occur inside the same transaction that deletes its owner.
|
1295
1377
|
# * <tt>:delete_all</tt> causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
|
1296
|
-
# * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+.
|
1297
|
-
#
|
1378
|
+
# * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Polymorphic type will also be nullified
|
1379
|
+
# on polymorphic associations. Callbacks are not executed.
|
1380
|
+
# * <tt>:restrict_with_exception</tt> causes an <tt>ActiveRecord::DeleteRestrictionError</tt> exception to be raised if there are any associated records.
|
1298
1381
|
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
|
1299
1382
|
#
|
1300
1383
|
# If using with the <tt>:through</tt> option, the association on the join model must be
|
@@ -1355,6 +1438,11 @@ module ActiveRecord
|
|
1355
1438
|
# Specifies a module or array of modules that will be extended into the association object returned.
|
1356
1439
|
# Useful for defining methods on associations, especially when they should be shared between multiple
|
1357
1440
|
# association objects.
|
1441
|
+
# [:strict_loading]
|
1442
|
+
# Enforces strict loading every time the associated record is loaded through this association.
|
1443
|
+
# [:ensuring_owner_was]
|
1444
|
+
# Specifies an instance method to be called on the owner. The method must return true in order for the
|
1445
|
+
# associated records to be deleted in a background job.
|
1358
1446
|
#
|
1359
1447
|
# Option examples:
|
1360
1448
|
# has_many :comments, -> { order("posted_on") }
|
@@ -1365,6 +1453,7 @@ module ActiveRecord
|
|
1365
1453
|
# has_many :tags, as: :taggable
|
1366
1454
|
# has_many :reports, -> { readonly }
|
1367
1455
|
# has_many :subscribers, through: :subscriptions, source: :user
|
1456
|
+
# has_many :comments, strict_loading: true
|
1368
1457
|
def has_many(name, scope = nil, **options, &extension)
|
1369
1458
|
reflection = Builder::HasMany.build(self, name, scope, options, &extension)
|
1370
1459
|
Reflection.add_reflection self, name, reflection
|
@@ -1434,10 +1523,15 @@ module ActiveRecord
|
|
1434
1523
|
# Controls what happens to the associated object when
|
1435
1524
|
# its owner is destroyed:
|
1436
1525
|
#
|
1526
|
+
# * <tt>nil</tt> do nothing (default).
|
1437
1527
|
# * <tt>:destroy</tt> causes the associated object to also be destroyed
|
1528
|
+
# * <tt>:destroy_async</tt> causes the associated object to be destroyed in a background job. <b>WARNING:</b> Do not use
|
1529
|
+
# this option if the association is backed by foreign key constraints in your database. The foreign key
|
1530
|
+
# constraint actions will occur inside the same transaction that deletes its owner.
|
1438
1531
|
# * <tt>:delete</tt> causes the associated object to be deleted directly from the database (so callbacks will not execute)
|
1439
|
-
# * <tt>:nullify</tt> causes the foreign key to be set to +NULL+.
|
1440
|
-
#
|
1532
|
+
# * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Polymorphic type column is also nullified
|
1533
|
+
# on polymorphic associations. Callbacks are not executed.
|
1534
|
+
# * <tt>:restrict_with_exception</tt> causes an <tt>ActiveRecord::DeleteRestrictionError</tt> exception to be raised if there is an associated record
|
1441
1535
|
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
|
1442
1536
|
#
|
1443
1537
|
# Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> option.
|
@@ -1492,6 +1586,11 @@ module ActiveRecord
|
|
1492
1586
|
# When set to +true+, the association will also have its presence validated.
|
1493
1587
|
# This will validate the association itself, not the id. You can use
|
1494
1588
|
# +:inverse_of+ to avoid an extra query during validation.
|
1589
|
+
# [:strict_loading]
|
1590
|
+
# Enforces strict loading every time the associated record is loaded through this association.
|
1591
|
+
# [:ensuring_owner_was]
|
1592
|
+
# Specifies an instance method to be called on the owner. The method must return true in order for the
|
1593
|
+
# associated records to be deleted in a background job.
|
1495
1594
|
#
|
1496
1595
|
# Option examples:
|
1497
1596
|
# has_one :credit_card, dependent: :destroy # destroys the associated credit card
|
@@ -1504,6 +1603,7 @@ module ActiveRecord
|
|
1504
1603
|
# has_one :club, through: :membership
|
1505
1604
|
# has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
|
1506
1605
|
# has_one :credit_card, required: true
|
1606
|
+
# has_one :credit_card, strict_loading: true
|
1507
1607
|
def has_one(name, scope = nil, **options)
|
1508
1608
|
reflection = Builder::HasOne.build(self, name, scope, options)
|
1509
1609
|
Reflection.add_reflection self, name, reflection
|
@@ -1524,6 +1624,7 @@ module ActiveRecord
|
|
1524
1624
|
# Returns the associated object. +nil+ is returned if none is found.
|
1525
1625
|
# [association=(associate)]
|
1526
1626
|
# Assigns the associate object, extracts the primary key, and sets it as the foreign key.
|
1627
|
+
# No modification or deletion of existing records takes place.
|
1527
1628
|
# [build_association(attributes = {})]
|
1528
1629
|
# Returns a new object of the associated type that has been instantiated
|
1529
1630
|
# with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
|
@@ -1581,10 +1682,11 @@ module ActiveRecord
|
|
1581
1682
|
# association will use "taggable_type" as the default <tt>:foreign_type</tt>.
|
1582
1683
|
# [:primary_key]
|
1583
1684
|
# Specify the method that returns the primary key of associated object used for the association.
|
1584
|
-
# By default this is id
|
1685
|
+
# By default this is +id+.
|
1585
1686
|
# [:dependent]
|
1586
1687
|
# If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
|
1587
|
-
# <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method.
|
1688
|
+
# <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. If set to
|
1689
|
+
# <tt>:destroy_async</tt>, the associated object is scheduled to be destroyed in a background job.
|
1588
1690
|
# This option should not be specified when #belongs_to is used in conjunction with
|
1589
1691
|
# a #has_many relationship on another class because of the potential to leave
|
1590
1692
|
# orphaned records behind.
|
@@ -1636,6 +1738,11 @@ module ActiveRecord
|
|
1636
1738
|
# [:default]
|
1637
1739
|
# Provide a callable (i.e. proc or lambda) to specify that the association should
|
1638
1740
|
# be initialized with a particular record before validation.
|
1741
|
+
# [:strict_loading]
|
1742
|
+
# Enforces strict loading every time the associated record is loaded through this association.
|
1743
|
+
# [:ensuring_owner_was]
|
1744
|
+
# Specifies an instance method to be called on the owner. The method must return true in order for the
|
1745
|
+
# associated records to be deleted in a background job.
|
1639
1746
|
#
|
1640
1747
|
# Option examples:
|
1641
1748
|
# belongs_to :firm, foreign_key: "client_of"
|
@@ -1650,6 +1757,7 @@ module ActiveRecord
|
|
1650
1757
|
# belongs_to :company, touch: :employees_last_updated_at
|
1651
1758
|
# belongs_to :user, optional: true
|
1652
1759
|
# belongs_to :account, default: -> { company.account }
|
1760
|
+
# belongs_to :account, strict_loading: true
|
1653
1761
|
def belongs_to(name, scope = nil, **options)
|
1654
1762
|
reflection = Builder::BelongsTo.build(self, name, scope, options)
|
1655
1763
|
Reflection.add_reflection self, name, reflection
|
@@ -1672,7 +1780,7 @@ module ActiveRecord
|
|
1672
1780
|
# The join table should not have a primary key or a model associated with it. You must manually generate the
|
1673
1781
|
# join table with a migration such as this:
|
1674
1782
|
#
|
1675
|
-
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[
|
1783
|
+
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[6.0]
|
1676
1784
|
# def change
|
1677
1785
|
# create_join_table :developers, :projects
|
1678
1786
|
# end
|
@@ -1761,6 +1869,7 @@ module ActiveRecord
|
|
1761
1869
|
# has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
|
1762
1870
|
# has_and_belongs_to_many :categories, ->(post) {
|
1763
1871
|
# where("default_category = ?", post.default_category)
|
1872
|
+
# }
|
1764
1873
|
#
|
1765
1874
|
# === Extensions
|
1766
1875
|
#
|
@@ -1811,6 +1920,8 @@ module ActiveRecord
|
|
1811
1920
|
#
|
1812
1921
|
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
|
1813
1922
|
# <tt>:autosave</tt> to <tt>true</tt>.
|
1923
|
+
# [:strict_loading]
|
1924
|
+
# Enforces strict loading every time an associated record is loaded through this association.
|
1814
1925
|
#
|
1815
1926
|
# Option examples:
|
1816
1927
|
# has_and_belongs_to_many :projects
|
@@ -1818,6 +1929,7 @@ module ActiveRecord
|
|
1818
1929
|
# has_and_belongs_to_many :nations, class_name: "Country"
|
1819
1930
|
# has_and_belongs_to_many :categories, join_table: "prods_cats"
|
1820
1931
|
# has_and_belongs_to_many :categories, -> { readonly }
|
1932
|
+
# has_and_belongs_to_many :categories, strict_loading: true
|
1821
1933
|
def has_and_belongs_to_many(name, scope = nil, **options, &extension)
|
1822
1934
|
habtm_reflection = ActiveRecord::Reflection::HasAndBelongsToManyReflection.new(name, scope, options, self)
|
1823
1935
|
|
@@ -1848,11 +1960,11 @@ module ActiveRecord
|
|
1848
1960
|
hm_options[:through] = middle_reflection.name
|
1849
1961
|
hm_options[:source] = join_model.right_reflection.name
|
1850
1962
|
|
1851
|
-
[:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend].each do |k|
|
1963
|
+
[:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend, :strict_loading].each do |k|
|
1852
1964
|
hm_options[k] = options[k] if options.key? k
|
1853
1965
|
end
|
1854
1966
|
|
1855
|
-
has_many name, scope, hm_options, &extension
|
1967
|
+
has_many name, scope, **hm_options, &extension
|
1856
1968
|
_reflections[name.to_s].parent_reflection = habtm_reflection
|
1857
1969
|
end
|
1858
1970
|
end
|