activerecord 7.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1607 -1040
- data/MIT-LICENSE +1 -1
- data/README.rdoc +17 -18
- data/lib/active_record/aggregations.rb +16 -13
- data/lib/active_record/association_relation.rb +1 -1
- data/lib/active_record/associations/association.rb +18 -3
- data/lib/active_record/associations/association_scope.rb +16 -9
- data/lib/active_record/associations/belongs_to_association.rb +14 -6
- data/lib/active_record/associations/builder/association.rb +3 -3
- data/lib/active_record/associations/builder/belongs_to.rb +21 -8
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +17 -12
- data/lib/active_record/associations/collection_proxy.rb +22 -12
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +27 -17
- data/lib/active_record/associations/has_many_through_association.rb +10 -6
- data/lib/active_record/associations/has_one_association.rb +10 -3
- data/lib/active_record/associations/join_dependency.rb +20 -14
- data/lib/active_record/associations/preloader/association.rb +27 -6
- data/lib/active_record/associations/preloader/through_association.rb +1 -1
- data/lib/active_record/associations/preloader.rb +13 -10
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +22 -11
- data/lib/active_record/associations.rb +345 -219
- data/lib/active_record/attribute_assignment.rb +0 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
- data/lib/active_record/attribute_methods/dirty.rb +40 -26
- data/lib/active_record/attribute_methods/primary_key.rb +76 -24
- data/lib/active_record/attribute_methods/query.rb +28 -16
- data/lib/active_record/attribute_methods/read.rb +18 -5
- data/lib/active_record/attribute_methods/serialization.rb +172 -69
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +110 -28
- data/lib/active_record/attributes.rb +3 -3
- data/lib/active_record/autosave_association.rb +56 -10
- data/lib/active_record/base.rb +10 -5
- data/lib/active_record/callbacks.rb +16 -32
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -34
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +164 -89
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +3 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +63 -43
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +128 -32
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +60 -22
- data/lib/active_record/connection_adapters/abstract/quoting.rb +52 -8
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +163 -29
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +302 -129
- data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
- data/lib/active_record/connection_adapters/abstract_adapter.rb +504 -106
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +217 -104
- data/lib/active_record/connection_adapters/column.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +23 -144
- data/lib/active_record/connection_adapters/mysql/quoting.rb +29 -12
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +38 -14
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +148 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +98 -53
- data/lib/active_record/connection_adapters/pool_config.rb +14 -5
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +72 -45
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +41 -8
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +6 -10
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +131 -2
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +358 -57
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +343 -181
- data/lib/active_record/connection_adapters/schema_cache.rb +287 -59
- data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +45 -39
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +22 -5
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +41 -22
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +242 -81
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +98 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
- data/lib/active_record/connection_adapters.rb +3 -1
- data/lib/active_record/connection_handling.rb +73 -96
- data/lib/active_record/core.rb +136 -148
- data/lib/active_record/counter_cache.rb +46 -25
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -0
- data/lib/active_record/database_configurations/database_config.rb +9 -3
- data/lib/active_record/database_configurations/hash_config.rb +22 -12
- data/lib/active_record/database_configurations/url_config.rb +17 -11
- data/lib/active_record/database_configurations.rb +87 -34
- data/lib/active_record/delegated_type.rb +9 -4
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +2 -0
- data/lib/active_record/disable_joins_association_relation.rb +1 -1
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
- data/lib/active_record/encryption/config.rb +25 -1
- data/lib/active_record/encryption/configurable.rb +13 -14
- data/lib/active_record/encryption/context.rb +10 -3
- data/lib/active_record/encryption/contexts.rb +8 -4
- data/lib/active_record/encryption/derived_secret_key_provider.rb +9 -3
- data/lib/active_record/encryption/deterministic_key_provider.rb +1 -1
- data/lib/active_record/encryption/encryptable_record.rb +38 -22
- data/lib/active_record/encryption/encrypted_attribute_type.rb +19 -8
- data/lib/active_record/encryption/encryptor.rb +7 -7
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +3 -3
- data/lib/active_record/encryption/extended_deterministic_queries.rb +83 -71
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
- data/lib/active_record/encryption/key_generator.rb +12 -1
- data/lib/active_record/encryption/message.rb +1 -1
- data/lib/active_record/encryption/message_serializer.rb +2 -0
- data/lib/active_record/encryption/properties.rb +4 -4
- data/lib/active_record/encryption/scheme.rb +20 -23
- data/lib/active_record/encryption.rb +1 -0
- data/lib/active_record/enum.rb +114 -27
- data/lib/active_record/errors.rb +108 -15
- data/lib/active_record/explain.rb +23 -3
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/model_metadata.rb +14 -4
- data/lib/active_record/fixture_set/render_context.rb +2 -0
- data/lib/active_record/fixture_set/table_row.rb +29 -8
- data/lib/active_record/fixtures.rb +121 -73
- data/lib/active_record/future_result.rb +30 -5
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/inheritance.rb +30 -16
- data/lib/active_record/insert_all.rb +55 -8
- data/lib/active_record/integration.rb +10 -10
- data/lib/active_record/internal_metadata.rb +118 -30
- data/lib/active_record/locking/optimistic.rb +32 -18
- data/lib/active_record/locking/pessimistic.rb +8 -5
- data/lib/active_record/log_subscriber.rb +39 -17
- data/lib/active_record/marshalling.rb +56 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
- data/lib/active_record/middleware/database_selector.rb +18 -13
- data/lib/active_record/middleware/shard_selector.rb +7 -5
- data/lib/active_record/migration/command_recorder.rb +104 -9
- data/lib/active_record/migration/compatibility.rb +158 -64
- data/lib/active_record/migration/default_strategy.rb +23 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration.rb +271 -117
- data/lib/active_record/model_schema.rb +82 -50
- data/lib/active_record/nested_attributes.rb +23 -3
- data/lib/active_record/normalization.rb +159 -0
- data/lib/active_record/persistence.rb +200 -47
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +3 -21
- data/lib/active_record/query_logs.rb +87 -51
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +16 -3
- data/lib/active_record/railtie.rb +127 -61
- data/lib/active_record/railties/controller_runtime.rb +12 -8
- data/lib/active_record/railties/databases.rake +142 -143
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +32 -5
- data/lib/active_record/reflection.rb +177 -45
- data/lib/active_record/relation/batches/batch_enumerator.rb +5 -3
- data/lib/active_record/relation/batches.rb +190 -61
- data/lib/active_record/relation/calculations.rb +200 -83
- data/lib/active_record/relation/delegation.rb +23 -9
- data/lib/active_record/relation/finder_methods.rb +77 -16
- data/lib/active_record/relation/merger.rb +2 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +26 -14
- data/lib/active_record/relation/query_attribute.rb +25 -1
- data/lib/active_record/relation/query_methods.rb +429 -76
- data/lib/active_record/relation/spawn_methods.rb +18 -1
- data/lib/active_record/relation.rb +98 -41
- data/lib/active_record/result.rb +25 -9
- data/lib/active_record/runtime_registry.rb +10 -1
- data/lib/active_record/sanitization.rb +57 -16
- data/lib/active_record/schema.rb +36 -22
- data/lib/active_record/schema_dumper.rb +65 -23
- data/lib/active_record/schema_migration.rb +68 -33
- data/lib/active_record/scoping/default.rb +20 -12
- data/lib/active_record/scoping/named.rb +2 -2
- data/lib/active_record/scoping.rb +2 -1
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/serialization.rb +5 -0
- data/lib/active_record/signed_id.rb +9 -7
- data/lib/active_record/store.rb +16 -11
- data/lib/active_record/suppressor.rb +3 -1
- data/lib/active_record/table_metadata.rb +16 -3
- data/lib/active_record/tasks/database_tasks.rb +138 -107
- data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +17 -15
- data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
- data/lib/active_record/test_fixtures.rb +123 -99
- data/lib/active_record/timestamp.rb +26 -14
- data/lib/active_record/token_for.rb +113 -0
- data/lib/active_record/touch_later.rb +11 -6
- data/lib/active_record/transactions.rb +39 -13
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +8 -4
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +3 -3
- data/lib/active_record/validations/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +50 -5
- data/lib/active_record/validations.rb +8 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +143 -16
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +1 -1
- data/lib/arel/nodes/and.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -1
- data/lib/arel/nodes/bound_sql_literal.rb +61 -0
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/filter.rb +1 -1
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/homogeneous_in.rb +0 -8
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/node.rb +111 -2
- data/lib/arel/nodes/sql_literal.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes.rb +4 -0
- data/lib/arel/predications.rb +2 -0
- data/lib/arel/table.rb +9 -5
- data/lib/arel/visitors/mysql.rb +8 -1
- data/lib/arel/visitors/to_sql.rb +81 -17
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +16 -2
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- metadata +50 -15
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -63
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Active Record -- Object-relational mapping in Rails
|
1
|
+
= Active Record -- Object-relational mapping in \Rails
|
2
2
|
|
3
3
|
Active Record connects classes to relational database tables to establish an
|
4
4
|
almost zero-configuration persistence layer for applications. The library
|
@@ -13,29 +13,28 @@ 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://
|
16
|
+
You can read more about Active Record in the {Active Record Basics}[https://guides.rubyonrails.org/active_record_basics.html] guide.
|
17
17
|
|
18
18
|
A short rundown of some of the major features:
|
19
19
|
|
20
20
|
* Automated mapping between classes and tables, attributes and columns.
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
{Learn more}[link:classes/ActiveRecord/Base.html]
|
22
|
+
class Product < ActiveRecord::Base
|
23
|
+
end
|
26
24
|
|
27
|
-
The Product class is automatically mapped to the table named "products",
|
28
|
-
which might look like this:
|
25
|
+
The Product class is automatically mapped to the table named "products",
|
26
|
+
which might look like this:
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
28
|
+
CREATE TABLE products (
|
29
|
+
id bigint NOT NULL auto_increment,
|
30
|
+
name varchar(255),
|
31
|
+
PRIMARY KEY (id)
|
32
|
+
);
|
35
33
|
|
36
|
-
This would also define the following accessors: <tt>Product#name</tt> and
|
37
|
-
<tt>Product#name=(new_name)</tt>.
|
34
|
+
This would also define the following accessors: <tt>Product#name</tt> and
|
35
|
+
<tt>Product#name=(new_name)</tt>.
|
38
36
|
|
37
|
+
{Learn more}[link:classes/ActiveRecord/Base.html]
|
39
38
|
|
40
39
|
* Associations between objects defined by simple class methods.
|
41
40
|
|
@@ -140,7 +139,7 @@ This would also define the following accessors: <tt>Product#name</tt> and
|
|
140
139
|
|
141
140
|
* Database agnostic schema management with Migrations.
|
142
141
|
|
143
|
-
class AddSystemSettings < ActiveRecord::Migration[7.
|
142
|
+
class AddSystemSettings < ActiveRecord::Migration[7.1]
|
144
143
|
def up
|
145
144
|
create_table :system_settings do |t|
|
146
145
|
t.string :name
|
@@ -192,7 +191,7 @@ The latest version of Active Record can be installed with RubyGems:
|
|
192
191
|
|
193
192
|
$ gem install activerecord
|
194
193
|
|
195
|
-
Source code can be downloaded as part of the Rails project on GitHub:
|
194
|
+
Source code can be downloaded as part of the \Rails project on GitHub:
|
196
195
|
|
197
196
|
* https://github.com/rails/rails/tree/main/activerecord
|
198
197
|
|
@@ -210,7 +209,7 @@ API documentation is at:
|
|
210
209
|
|
211
210
|
* https://api.rubyonrails.org
|
212
211
|
|
213
|
-
Bug reports for the Ruby on Rails project can be filed here:
|
212
|
+
Bug reports for the Ruby on \Rails project can be filed here:
|
214
213
|
|
215
214
|
* https://github.com/rails/rails/issues
|
216
215
|
|
@@ -4,7 +4,7 @@ module ActiveRecord
|
|
4
4
|
# See ActiveRecord::Aggregations::ClassMethods for documentation
|
5
5
|
module Aggregations
|
6
6
|
def initialize_dup(*) # :nodoc:
|
7
|
-
@aggregation_cache =
|
7
|
+
@aggregation_cache = @aggregation_cache.dup
|
8
8
|
super
|
9
9
|
end
|
10
10
|
|
@@ -19,10 +19,12 @@ module ActiveRecord
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def init_internals
|
22
|
-
@aggregation_cache = {}
|
23
22
|
super
|
23
|
+
@aggregation_cache = {}
|
24
24
|
end
|
25
25
|
|
26
|
+
# = Active Record \Aggregations
|
27
|
+
#
|
26
28
|
# Active Record implements aggregation through a macro-like class method called #composed_of
|
27
29
|
# for representing attributes as value objects. It expresses relationships like "Account [is]
|
28
30
|
# composed of Money [among other things]" or "Person [is] composed of [an] address". Each call
|
@@ -32,8 +34,8 @@ module ActiveRecord
|
|
32
34
|
# the database).
|
33
35
|
#
|
34
36
|
# class Customer < ActiveRecord::Base
|
35
|
-
# composed_of :balance, class_name: "Money", mapping:
|
36
|
-
# composed_of :address, mapping:
|
37
|
+
# composed_of :balance, class_name: "Money", mapping: { balance: :amount }
|
38
|
+
# composed_of :address, mapping: { address_street: :street, address_city: :city }
|
37
39
|
# end
|
38
40
|
#
|
39
41
|
# The customer class now has the following methods to manipulate the value objects:
|
@@ -150,7 +152,7 @@ module ActiveRecord
|
|
150
152
|
# class NetworkResource < ActiveRecord::Base
|
151
153
|
# composed_of :cidr,
|
152
154
|
# class_name: 'NetAddr::CIDR',
|
153
|
-
# mapping:
|
155
|
+
# mapping: { network_address: :network, cidr_range: :bits },
|
154
156
|
# allow_nil: true,
|
155
157
|
# constructor: Proc.new { |network_address, cidr_range| NetAddr::CIDR.create("#{network_address}/#{cidr_range}") },
|
156
158
|
# converter: Proc.new { |value| NetAddr::CIDR.create(value.is_a?(Array) ? value.join('/') : value) }
|
@@ -188,10 +190,10 @@ module ActiveRecord
|
|
188
190
|
# to the Address class, but if the real class name is +CompanyAddress+, you'll have to specify it
|
189
191
|
# with this option.
|
190
192
|
# * <tt>:mapping</tt> - Specifies the mapping of entity attributes to attributes of the value
|
191
|
-
# object. Each mapping is represented as
|
192
|
-
# entity attribute and the
|
193
|
+
# object. Each mapping is represented as a key-value pair where the key is the name of the
|
194
|
+
# entity attribute and the value is the name of the attribute in the value object. The
|
193
195
|
# order in which mappings are defined determines the order in which attributes are sent to the
|
194
|
-
# value class constructor.
|
196
|
+
# value class constructor. The mapping can be written as a hash or as an array of pairs.
|
195
197
|
# * <tt>:allow_nil</tt> - Specifies that the value object will not be instantiated when all mapped
|
196
198
|
# attributes are +nil+. Setting the value object to +nil+ has the effect of writing +nil+ to all
|
197
199
|
# mapped attributes.
|
@@ -208,14 +210,15 @@ module ActiveRecord
|
|
208
210
|
# can return +nil+ to skip the assignment.
|
209
211
|
#
|
210
212
|
# Option examples:
|
211
|
-
# composed_of :temperature, mapping:
|
212
|
-
# composed_of :balance, class_name: "Money", mapping:
|
213
|
+
# composed_of :temperature, mapping: { reading: :celsius }
|
214
|
+
# composed_of :balance, class_name: "Money", mapping: { balance: :amount }
|
215
|
+
# composed_of :address, mapping: { address_street: :street, address_city: :city }
|
213
216
|
# composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
|
214
217
|
# composed_of :gps_location
|
215
218
|
# composed_of :gps_location, allow_nil: true
|
216
219
|
# composed_of :ip_address,
|
217
220
|
# class_name: 'IPAddr',
|
218
|
-
# mapping:
|
221
|
+
# mapping: { ip: :to_i },
|
219
222
|
# constructor: Proc.new { |ip| IPAddr.new(ip, Socket::AF_INET) },
|
220
223
|
# converter: Proc.new { |ip| ip.is_a?(Integer) ? IPAddr.new(ip, Socket::AF_INET) : IPAddr.new(ip.to_s) }
|
221
224
|
#
|
@@ -249,7 +252,7 @@ module ActiveRecord
|
|
249
252
|
object = constructor.respond_to?(:call) ?
|
250
253
|
constructor.call(*attrs) :
|
251
254
|
class_name.constantize.send(constructor, *attrs)
|
252
|
-
@aggregation_cache[name] = object
|
255
|
+
@aggregation_cache[name] = object.freeze
|
253
256
|
end
|
254
257
|
@aggregation_cache[name]
|
255
258
|
end
|
@@ -275,7 +278,7 @@ module ActiveRecord
|
|
275
278
|
@aggregation_cache[name] = nil
|
276
279
|
else
|
277
280
|
mapping.each { |key, value| write_attribute(key, part.send(value)) }
|
278
|
-
@aggregation_cache[name] = part.freeze
|
281
|
+
@aggregation_cache[name] = part.dup.freeze
|
279
282
|
end
|
280
283
|
end
|
281
284
|
end
|
@@ -16,7 +16,7 @@ module ActiveRecord
|
|
16
16
|
end
|
17
17
|
|
18
18
|
%w(insert insert_all insert! insert_all! upsert upsert_all).each do |method|
|
19
|
-
class_eval <<~RUBY
|
19
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
20
20
|
def #{method}(attributes, **kwargs)
|
21
21
|
if @association.reflection.through_reflection?
|
22
22
|
raise ArgumentError, "Bulk insert or upsert is currently not supported for has_many through association"
|
@@ -19,7 +19,7 @@ module ActiveRecord
|
|
19
19
|
# Associations in Active Record are middlemen between the object that
|
20
20
|
# holds the association, known as the <tt>owner</tt>, and the associated
|
21
21
|
# result set, known as the <tt>target</tt>. Association metadata is available in
|
22
|
-
# <tt>reflection</tt>, which is an instance of
|
22
|
+
# <tt>reflection</tt>, which is an instance of +ActiveRecord::Reflection::AssociationReflection+.
|
23
23
|
#
|
24
24
|
# For example, given
|
25
25
|
#
|
@@ -45,6 +45,8 @@ module ActiveRecord
|
|
45
45
|
|
46
46
|
reset
|
47
47
|
reset_scope
|
48
|
+
|
49
|
+
@skip_strict_loading = nil
|
48
50
|
end
|
49
51
|
|
50
52
|
# Resets the \loaded flag to +false+ and sets the \target to +nil+.
|
@@ -216,7 +218,7 @@ module ActiveRecord
|
|
216
218
|
end
|
217
219
|
|
218
220
|
def find_target
|
219
|
-
if violates_strict_loading?
|
221
|
+
if violates_strict_loading?
|
220
222
|
Base.strict_loading_violation!(owner: owner.class, reflection: reflection)
|
221
223
|
end
|
222
224
|
|
@@ -239,7 +241,19 @@ module ActiveRecord
|
|
239
241
|
end
|
240
242
|
end
|
241
243
|
|
244
|
+
def skip_strict_loading(&block)
|
245
|
+
skip_strict_loading_was = @skip_strict_loading
|
246
|
+
@skip_strict_loading = true
|
247
|
+
yield
|
248
|
+
ensure
|
249
|
+
@skip_strict_loading = skip_strict_loading_was
|
250
|
+
end
|
251
|
+
|
242
252
|
def violates_strict_loading?
|
253
|
+
return if @skip_strict_loading
|
254
|
+
|
255
|
+
return unless owner.validation_context.nil?
|
256
|
+
|
243
257
|
return reflection.strict_loading? if reflection.options.key?(:strict_loading)
|
244
258
|
|
245
259
|
owner.strict_loading? && !owner.strict_loading_n_plus_one_only?
|
@@ -322,7 +336,8 @@ module ActiveRecord
|
|
322
336
|
|
323
337
|
# Returns true if record contains the foreign_key
|
324
338
|
def foreign_key_for?(record)
|
325
|
-
|
339
|
+
foreign_key = Array(reflection.foreign_key)
|
340
|
+
foreign_key.all? { |key| record._has_attribute?(key) }
|
326
341
|
end
|
327
342
|
|
328
343
|
# This should be implemented to return the values of the relevant key(s) on the owner,
|
@@ -35,7 +35,7 @@ module ActiveRecord
|
|
35
35
|
binds = []
|
36
36
|
last_reflection = chain.last
|
37
37
|
|
38
|
-
binds
|
38
|
+
binds.push(*last_reflection.join_id_for(owner))
|
39
39
|
if last_reflection.type
|
40
40
|
binds << owner.class.polymorphic_name
|
41
41
|
end
|
@@ -56,12 +56,15 @@ module ActiveRecord
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def last_chain_scope(scope, reflection, owner)
|
59
|
-
primary_key = reflection.join_primary_key
|
60
|
-
foreign_key = reflection.join_foreign_key
|
59
|
+
primary_key = Array(reflection.join_primary_key)
|
60
|
+
foreign_key = Array(reflection.join_foreign_key)
|
61
61
|
|
62
62
|
table = reflection.aliased_table
|
63
|
-
|
64
|
-
|
63
|
+
primary_key_foreign_key_pairs = primary_key.zip(foreign_key)
|
64
|
+
primary_key_foreign_key_pairs.each do |join_key, foreign_key|
|
65
|
+
value = transform_value(owner._read_attribute(foreign_key))
|
66
|
+
scope = apply_scope(scope, table, join_key, value)
|
67
|
+
end
|
65
68
|
|
66
69
|
if reflection.type
|
67
70
|
polymorphic_type = transform_value(owner.class.polymorphic_name)
|
@@ -76,19 +79,23 @@ module ActiveRecord
|
|
76
79
|
end
|
77
80
|
|
78
81
|
def next_chain_scope(scope, reflection, next_reflection)
|
79
|
-
primary_key = reflection.join_primary_key
|
80
|
-
foreign_key = reflection.join_foreign_key
|
82
|
+
primary_key = Array(reflection.join_primary_key)
|
83
|
+
foreign_key = Array(reflection.join_foreign_key)
|
81
84
|
|
82
85
|
table = reflection.aliased_table
|
83
86
|
foreign_table = next_reflection.aliased_table
|
84
|
-
|
87
|
+
|
88
|
+
primary_key_foreign_key_pairs = primary_key.zip(foreign_key)
|
89
|
+
constraints = primary_key_foreign_key_pairs.map do |join_primary_key, foreign_key|
|
90
|
+
table[join_primary_key].eq(foreign_table[foreign_key])
|
91
|
+
end.inject(&:and)
|
85
92
|
|
86
93
|
if reflection.type
|
87
94
|
value = transform_value(next_reflection.klass.polymorphic_name)
|
88
95
|
scope = apply_scope(scope, table, reflection.type, value)
|
89
96
|
end
|
90
97
|
|
91
|
-
scope.joins!(join(foreign_table,
|
98
|
+
scope.joins!(join(foreign_table, constraints))
|
92
99
|
end
|
93
100
|
|
94
101
|
class ReflectionProxy < SimpleDelegator # :nodoc:
|
@@ -11,8 +11,13 @@ module ActiveRecord
|
|
11
11
|
when :destroy
|
12
12
|
raise ActiveRecord::Rollback unless target.destroy
|
13
13
|
when :destroy_async
|
14
|
-
|
15
|
-
|
14
|
+
if reflection.foreign_key.is_a?(Array)
|
15
|
+
primary_key_column = reflection.active_record_primary_key.map(&:to_sym)
|
16
|
+
id = reflection.foreign_key.map { |col| owner.public_send(col.to_sym) }
|
17
|
+
else
|
18
|
+
primary_key_column = reflection.active_record_primary_key.to_sym
|
19
|
+
id = owner.public_send(reflection.foreign_key.to_sym)
|
20
|
+
end
|
16
21
|
|
17
22
|
enqueue_destroy_association(
|
18
23
|
owner_model_name: owner.class.to_s,
|
@@ -119,10 +124,13 @@ module ActiveRecord
|
|
119
124
|
end
|
120
125
|
|
121
126
|
def replace_keys(record, force: false)
|
122
|
-
|
127
|
+
target_key_values = record ? Array(primary_key(record.class)).map { |key| record._read_attribute(key) } : []
|
128
|
+
reflection_fk = Array(reflection.foreign_key)
|
123
129
|
|
124
|
-
if force || owner._read_attribute(
|
125
|
-
|
130
|
+
if force || reflection_fk.map { |fk| owner._read_attribute(fk) } != target_key_values
|
131
|
+
reflection_fk.zip(target_key_values).each do |key, value|
|
132
|
+
owner[key] = value
|
133
|
+
end
|
126
134
|
end
|
127
135
|
end
|
128
136
|
|
@@ -131,7 +139,7 @@ module ActiveRecord
|
|
131
139
|
end
|
132
140
|
|
133
141
|
def foreign_key_present?
|
134
|
-
|
142
|
+
Array(reflection.foreign_key).all? { |fk| owner._read_attribute(fk) }
|
135
143
|
end
|
136
144
|
|
137
145
|
def invertible_for?(record)
|
@@ -19,7 +19,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
19
19
|
self.extensions = []
|
20
20
|
|
21
21
|
VALID_OPTIONS = [
|
22
|
-
:class_name, :anonymous_class, :primary_key, :foreign_key, :dependent, :validate, :inverse_of, :strict_loading
|
22
|
+
:class_name, :anonymous_class, :primary_key, :foreign_key, :dependent, :validate, :inverse_of, :strict_loading, :query_constraints
|
23
23
|
].freeze # :nodoc:
|
24
24
|
|
25
25
|
def self.build(model, name, scope, options, &block)
|
@@ -128,8 +128,8 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
128
128
|
|
129
129
|
def self.check_dependent_options(dependent, model)
|
130
130
|
if dependent == :destroy_async && !model.destroy_association_async_job
|
131
|
-
err_message = "
|
132
|
-
raise ActiveRecord::
|
131
|
+
err_message = "A valid destroy_association_async_job is required to use `dependent: :destroy_async` on associations"
|
132
|
+
raise ActiveRecord::ConfigurationError, err_message
|
133
133
|
end
|
134
134
|
unless valid_dependent_options.include? dependent
|
135
135
|
raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{dependent}"
|
@@ -37,10 +37,10 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
37
37
|
}
|
38
38
|
|
39
39
|
klass = reflection.class_name.safe_constantize
|
40
|
-
klass.
|
40
|
+
klass._counter_cache_columns |= [cache_column] if klass && klass.respond_to?(:_counter_cache_columns)
|
41
41
|
end
|
42
42
|
|
43
|
-
def self.touch_record(o, changes, foreign_key, name, touch
|
43
|
+
def self.touch_record(o, changes, foreign_key, name, touch) # :nodoc:
|
44
44
|
old_foreign_id = changes[foreign_key] && changes[foreign_key].first
|
45
45
|
|
46
46
|
if old_foreign_id
|
@@ -58,9 +58,9 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
58
58
|
|
59
59
|
if old_record
|
60
60
|
if touch != true
|
61
|
-
old_record.
|
61
|
+
old_record.touch_later(touch)
|
62
62
|
else
|
63
|
-
old_record.
|
63
|
+
old_record.touch_later
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -68,9 +68,9 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
68
68
|
record = o.public_send name
|
69
69
|
if record && record.persisted?
|
70
70
|
if touch != true
|
71
|
-
record.
|
71
|
+
record.touch_later(touch)
|
72
72
|
else
|
73
|
-
record.
|
73
|
+
record.touch_later
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
@@ -81,7 +81,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
81
81
|
touch = reflection.options[:touch]
|
82
82
|
|
83
83
|
callback = lambda { |changes_method| lambda { |record|
|
84
|
-
BelongsTo.touch_record(record, record.send(changes_method), foreign_key, name, touch
|
84
|
+
BelongsTo.touch_record(record, record.send(changes_method), foreign_key, name, touch)
|
85
85
|
}}
|
86
86
|
|
87
87
|
if reflection.counter_cache_column
|
@@ -123,7 +123,20 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
123
123
|
super
|
124
124
|
|
125
125
|
if required
|
126
|
-
|
126
|
+
if ActiveRecord.belongs_to_required_validates_foreign_key
|
127
|
+
model.validates_presence_of reflection.name, message: :required
|
128
|
+
else
|
129
|
+
condition = lambda { |record|
|
130
|
+
foreign_key = reflection.foreign_key
|
131
|
+
foreign_type = reflection.foreign_type
|
132
|
+
|
133
|
+
record.read_attribute(foreign_key).nil? ||
|
134
|
+
record.attribute_changed?(foreign_key) ||
|
135
|
+
(reflection.polymorphic? && (record.read_attribute(foreign_type).nil? || record.attribute_changed?(foreign_type)))
|
136
|
+
}
|
137
|
+
|
138
|
+
model.validates_presence_of reflection.name, message: :required, if: condition
|
139
|
+
end
|
127
140
|
end
|
128
141
|
end
|
129
142
|
|
@@ -20,6 +20,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
20
20
|
attr_accessor :right_reflection
|
21
21
|
end
|
22
22
|
|
23
|
+
@table_name = nil
|
23
24
|
def self.table_name
|
24
25
|
# Table name needs to be resolved lazily
|
25
26
|
# because RHS class might not have been loaded
|
@@ -44,11 +45,6 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
44
45
|
def self.retrieve_connection
|
45
46
|
left_model.retrieve_connection
|
46
47
|
end
|
47
|
-
|
48
|
-
private
|
49
|
-
def self.suppress_composite_primary_key(pk)
|
50
|
-
pk unless pk.is_a?(Array)
|
51
|
-
end
|
52
48
|
}
|
53
49
|
|
54
50
|
join_model.name = "HABTM_#{association_name.to_s.camelize}"
|
@@ -16,7 +16,7 @@ module ActiveRecord
|
|
16
16
|
#
|
17
17
|
# The CollectionAssociation class provides common methods to the collections
|
18
18
|
# defined by +has_and_belongs_to_many+, +has_many+ or +has_many+ with
|
19
|
-
# the
|
19
|
+
# the <tt>:through association</tt> option.
|
20
20
|
#
|
21
21
|
# You need to be careful with assumptions regarding the target: The proxy
|
22
22
|
# does not fetch records from the database until it needs them, but new
|
@@ -61,14 +61,20 @@ module ActiveRecord
|
|
61
61
|
primary_key = reflection.association_primary_key
|
62
62
|
pk_type = klass.type_for_attribute(primary_key)
|
63
63
|
ids = Array(ids).compact_blank
|
64
|
-
ids.map! { |
|
64
|
+
ids.map! { |id| pk_type.cast(id) }
|
65
65
|
|
66
|
-
records = klass.
|
67
|
-
|
66
|
+
records = if klass.composite_primary_key?
|
67
|
+
klass.where(primary_key => ids).index_by do |record|
|
68
|
+
primary_key.map { |primary_key| record._read_attribute(primary_key) }
|
69
|
+
end
|
70
|
+
else
|
71
|
+
klass.where(primary_key => ids).index_by do |record|
|
72
|
+
record._read_attribute(primary_key)
|
73
|
+
end
|
68
74
|
end.values_at(*ids).compact
|
69
75
|
|
70
76
|
if records.size != ids.size
|
71
|
-
found_ids = records.map { |record| record.
|
77
|
+
found_ids = records.map { |record| record._read_attribute(primary_key) }
|
72
78
|
not_found_ids = ids - found_ids
|
73
79
|
klass.all.raise_record_not_found_exception!(ids, records.size, ids.size, primary_key, not_found_ids)
|
74
80
|
else
|
@@ -79,7 +85,7 @@ module ActiveRecord
|
|
79
85
|
def reset
|
80
86
|
super
|
81
87
|
@target = []
|
82
|
-
@replaced_or_added_targets = Set.new
|
88
|
+
@replaced_or_added_targets = Set.new.compare_by_identity
|
83
89
|
@association_ids = nil
|
84
90
|
end
|
85
91
|
|
@@ -119,7 +125,7 @@ module ActiveRecord
|
|
119
125
|
def concat(*records)
|
120
126
|
records = records.flatten
|
121
127
|
if owner.new_record?
|
122
|
-
load_target
|
128
|
+
skip_strict_loading { load_target }
|
123
129
|
concat_records(records)
|
124
130
|
else
|
125
131
|
transaction { concat_records(records) }
|
@@ -180,7 +186,7 @@ module ActiveRecord
|
|
180
186
|
end
|
181
187
|
|
182
188
|
# Deletes the +records+ and removes them from this association calling
|
183
|
-
# +before_remove
|
189
|
+
# +before_remove+, +after_remove+, +before_destroy+ and +after_destroy+ callbacks.
|
184
190
|
#
|
185
191
|
# Note that this method removes records from the database ignoring the
|
186
192
|
# +:dependent+ option.
|
@@ -233,7 +239,7 @@ module ActiveRecord
|
|
233
239
|
# and delete/add only records that have changed.
|
234
240
|
def replace(other_array)
|
235
241
|
other_array.each { |val| raise_on_type_mismatch!(val) }
|
236
|
-
original_target = load_target.dup
|
242
|
+
original_target = skip_strict_loading { load_target }.dup
|
237
243
|
|
238
244
|
if owner.new_record?
|
239
245
|
replace_records(other_array, original_target)
|
@@ -320,13 +326,12 @@ module ActiveRecord
|
|
320
326
|
# * Otherwise, attributes should have the value found in the database
|
321
327
|
def merge_target_lists(persisted, memory)
|
322
328
|
return persisted if memory.empty?
|
323
|
-
return memory if persisted.empty?
|
324
329
|
|
325
330
|
persisted.map! do |record|
|
326
331
|
if mem_record = memory.delete(record)
|
327
332
|
|
328
|
-
((record.attribute_names & mem_record.attribute_names) - mem_record.changed_attribute_names_to_save).each do |name|
|
329
|
-
mem_record
|
333
|
+
((record.attribute_names & mem_record.attribute_names) - mem_record.changed_attribute_names_to_save - mem_record.class._attr_readonly).each do |name|
|
334
|
+
mem_record._write_attribute(name, record[name])
|
330
335
|
end
|
331
336
|
|
332
337
|
mem_record
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Associations
|
5
|
+
# = Active Record Collection Proxy
|
6
|
+
#
|
5
7
|
# Collection proxies in Active Record are middlemen between an
|
6
8
|
# <tt>association</tt>, and its <tt>target</tt> result set.
|
7
9
|
#
|
@@ -94,12 +96,12 @@ module ActiveRecord
|
|
94
96
|
# receive:
|
95
97
|
#
|
96
98
|
# person.pets.select(:name).first.person_id
|
97
|
-
# # => ActiveModel::MissingAttributeError: missing attribute
|
99
|
+
# # => ActiveModel::MissingAttributeError: missing attribute 'person_id' for Pet
|
98
100
|
#
|
99
|
-
# *Second:* You can pass a block so it can be used just like Array#select
|
101
|
+
# *Second:* You can pass a block so it can be used just like <tt>Array#select</tt>.
|
100
102
|
# This builds an array of objects from the database for the scope,
|
101
103
|
# converting them into an array and iterating through them using
|
102
|
-
# Array#select
|
104
|
+
# <tt>Array#select</tt>.
|
103
105
|
#
|
104
106
|
# person.pets.select { |pet| /oo/.match?(pet.name) }
|
105
107
|
# # => [
|
@@ -108,7 +110,7 @@ module ActiveRecord
|
|
108
110
|
# # ]
|
109
111
|
|
110
112
|
# Finds an object in the collection responding to the +id+. Uses the same
|
111
|
-
# rules as ActiveRecord::
|
113
|
+
# rules as ActiveRecord::FinderMethods.find. Returns ActiveRecord::RecordNotFound
|
112
114
|
# error if the object cannot be found.
|
113
115
|
#
|
114
116
|
# class Person < ActiveRecord::Base
|
@@ -218,7 +220,7 @@ module ActiveRecord
|
|
218
220
|
# :call-seq:
|
219
221
|
# third_to_last()
|
220
222
|
#
|
221
|
-
# Same as #
|
223
|
+
# Same as #last except returns only the third-to-last record.
|
222
224
|
|
223
225
|
##
|
224
226
|
# :method: second_to_last
|
@@ -226,7 +228,7 @@ module ActiveRecord
|
|
226
228
|
# :call-seq:
|
227
229
|
# second_to_last()
|
228
230
|
#
|
229
|
-
# Same as #
|
231
|
+
# Same as #last except returns only the second-to-last record.
|
230
232
|
|
231
233
|
# Returns the last record, or the last +n+ records, from the collection.
|
232
234
|
# If the collection is empty, the first form returns +nil+, and the second
|
@@ -260,7 +262,7 @@ module ActiveRecord
|
|
260
262
|
end
|
261
263
|
|
262
264
|
# Gives a record (or N records if a parameter is supplied) from the collection
|
263
|
-
# using the same rules as
|
265
|
+
# using the same rules as ActiveRecord::FinderMethods.take.
|
264
266
|
#
|
265
267
|
# class Person < ActiveRecord::Base
|
266
268
|
# has_many :pets
|
@@ -382,7 +384,7 @@ module ActiveRecord
|
|
382
384
|
# # => [#<Pet id: 2, name: "Puff", group: "celebrities", person_id: 1>]
|
383
385
|
#
|
384
386
|
# If the supplied array has an incorrect association type, it raises
|
385
|
-
# an
|
387
|
+
# an ActiveRecord::AssociationTypeMismatch error:
|
386
388
|
#
|
387
389
|
# person.pets.replace(["doo", "ggie", "gaga"])
|
388
390
|
# # => ActiveRecord::AssociationTypeMismatch: Pet expected, got String
|
@@ -475,7 +477,7 @@ module ActiveRecord
|
|
475
477
|
|
476
478
|
# Deletes the records of the collection directly from the database
|
477
479
|
# ignoring the +:dependent+ option. Records are instantiated and it
|
478
|
-
# invokes +before_remove+, +after_remove
|
480
|
+
# invokes +before_remove+, +after_remove+, +before_destroy+, and
|
479
481
|
# +after_destroy+ callbacks.
|
480
482
|
#
|
481
483
|
# class Person < ActiveRecord::Base
|
@@ -930,7 +932,7 @@ module ActiveRecord
|
|
930
932
|
@association
|
931
933
|
end
|
932
934
|
|
933
|
-
# Returns a
|
935
|
+
# Returns a Relation object for the records in this association
|
934
936
|
def scope
|
935
937
|
@scope ||= @association.scope
|
936
938
|
end
|
@@ -955,10 +957,13 @@ module ActiveRecord
|
|
955
957
|
# person.pets == other
|
956
958
|
# # => true
|
957
959
|
#
|
960
|
+
#
|
961
|
+
# Note that unpersisted records can still be seen as equal:
|
962
|
+
#
|
958
963
|
# other = [Pet.new(id: 1), Pet.new(id: 2)]
|
959
964
|
#
|
960
965
|
# person.pets == other
|
961
|
-
# # =>
|
966
|
+
# # => true
|
962
967
|
def ==(other)
|
963
968
|
load_target == other
|
964
969
|
end
|
@@ -1102,13 +1107,18 @@ module ActiveRecord
|
|
1102
1107
|
super
|
1103
1108
|
end
|
1104
1109
|
|
1110
|
+
def pretty_print(pp) # :nodoc:
|
1111
|
+
load_target if find_from_target?
|
1112
|
+
super
|
1113
|
+
end
|
1114
|
+
|
1105
1115
|
delegate_methods = [
|
1106
1116
|
QueryMethods,
|
1107
1117
|
SpawnMethods,
|
1108
1118
|
].flat_map { |klass|
|
1109
1119
|
klass.public_instance_methods(false)
|
1110
1120
|
} - self.public_instance_methods(false) - [:select] + [
|
1111
|
-
:scoping, :values, :insert, :insert_all, :insert!, :insert_all!, :upsert, :upsert_all
|
1121
|
+
:scoping, :values, :insert, :insert_all, :insert!, :insert_all!, :upsert, :upsert_all, :load_async
|
1112
1122
|
]
|
1113
1123
|
|
1114
1124
|
delegate(*delegate_methods, to: :scope)
|