activerecord 7.0.2.3 → 7.0.3.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +80 -0
  3. data/lib/active_record/associations/collection_association.rb +1 -1
  4. data/lib/active_record/associations/collection_proxy.rb +1 -1
  5. data/lib/active_record/associations.rb +9 -9
  6. data/lib/active_record/attribute_methods/serialization.rb +34 -50
  7. data/lib/active_record/attribute_methods.rb +1 -1
  8. data/lib/active_record/base.rb +3 -3
  9. data/lib/active_record/coders/yaml_column.rb +9 -7
  10. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +1 -1
  11. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +4 -0
  12. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +3 -3
  13. data/lib/active_record/connection_adapters/abstract_adapter.rb +5 -5
  14. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +4 -0
  15. data/lib/active_record/connection_adapters/mysql/quoting.rb +3 -1
  16. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +19 -1
  17. data/lib/active_record/connection_adapters/postgresql/quoting.rb +1 -1
  18. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +2 -0
  19. data/lib/active_record/connection_adapters/postgresql_adapter.rb +3 -3
  20. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +1 -1
  21. data/lib/active_record/connection_handling.rb +2 -2
  22. data/lib/active_record/core.rb +3 -3
  23. data/lib/active_record/encryption/configurable.rb +8 -2
  24. data/lib/active_record/encryption/contexts.rb +3 -3
  25. data/lib/active_record/encryption/derived_secret_key_provider.rb +1 -1
  26. data/lib/active_record/encryption/deterministic_key_provider.rb +1 -1
  27. data/lib/active_record/encryption/encryptable_record.rb +2 -4
  28. data/lib/active_record/encryption/encrypted_attribute_type.rb +2 -2
  29. data/lib/active_record/encryption/encryptor.rb +7 -7
  30. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +3 -3
  31. data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -4
  32. data/lib/active_record/encryption/scheme.rb +1 -1
  33. data/lib/active_record/enum.rb +1 -1
  34. data/lib/active_record/fixtures.rb +4 -4
  35. data/lib/active_record/gem_version.rb +3 -3
  36. data/lib/active_record/locking/pessimistic.rb +3 -3
  37. data/lib/active_record/log_subscriber.rb +10 -5
  38. data/lib/active_record/middleware/database_selector.rb +13 -6
  39. data/lib/active_record/middleware/shard_selector.rb +4 -4
  40. data/lib/active_record/migration/command_recorder.rb +3 -3
  41. data/lib/active_record/migration/compatibility.rb +7 -26
  42. data/lib/active_record/migration.rb +5 -4
  43. data/lib/active_record/model_schema.rb +1 -1
  44. data/lib/active_record/persistence.rb +9 -8
  45. data/lib/active_record/querying.rb +1 -1
  46. data/lib/active_record/railtie.rb +32 -0
  47. data/lib/active_record/railties/databases.rake +1 -1
  48. data/lib/active_record/reflection.rb +6 -0
  49. data/lib/active_record/relation/batches.rb +3 -3
  50. data/lib/active_record/relation/query_methods.rb +8 -1
  51. data/lib/active_record/relation.rb +6 -6
  52. data/lib/active_record/sanitization.rb +6 -5
  53. data/lib/active_record/scoping/default.rb +1 -5
  54. data/lib/active_record/serialization.rb +5 -0
  55. data/lib/active_record/signed_id.rb +1 -1
  56. data/lib/active_record/tasks/database_tasks.rb +26 -21
  57. data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -2
  58. data/lib/active_record/test_fixtures.rb +3 -0
  59. data/lib/active_record/translation.rb +1 -1
  60. data/lib/active_record/validations/associated.rb +3 -3
  61. data/lib/active_record/validations/presence.rb +2 -2
  62. data/lib/active_record/validations/uniqueness.rb +3 -3
  63. data/lib/active_record/version.rb +1 -1
  64. data/lib/active_record.rb +14 -0
  65. metadata +10 -10
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module Encryption
5
- # A +KeyProvider+ that derives keys from passwords.
5
+ # A KeyProvider that derives keys from passwords.
6
6
  class DerivedSecretKeyProvider < KeyProvider
7
7
  def initialize(passwords)
8
8
  super(Array(passwords).collect { |password| Key.derive_from(password) })
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module Encryption
5
- # A +KeyProvider+ that derives keys from passwords.
5
+ # A KeyProvider that derives keys from passwords.
6
6
  class DeterministicKeyProvider < DerivedSecretKeyProvider
7
7
  def initialize(password)
8
8
  passwords = Array(password)
@@ -18,12 +18,10 @@ module ActiveRecord
18
18
  #
19
19
  # === Options
20
20
  #
21
- # * <tt>:key_provider</tt> - Configure a +KeyProvider+ for serving the keys to encrypt and
22
- # decrypt this attribute. If not provided, it will default to +ActiveRecord::Encryption.key_provider+.
21
+ # * <tt>:key_provider</tt> - A key provider to provide encryption and decryption keys. Defaults to
22
+ # +ActiveRecord::Encryption.key_provider+.
23
23
  # * <tt>:key</tt> - A password to derive the key from. It's a shorthand for a +:key_provider+ that
24
24
  # serves derivated keys. Both options can't be used at the same time.
25
- # * <tt>:key_provider</tt> - Set a +:key_provider+ to provide encryption and decryption keys. If not
26
- # provided, it will default to the key provider set with `config.key_provider`.
27
25
  # * <tt>:deterministic</tt> - By default, encryption is not deterministic. It will use a random
28
26
  # initialization vector for each encryption operation. This means that encrypting the same content
29
27
  # with the same key twice will generate different ciphertexts. When set to +true+, it will generate the
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module Encryption
5
- # An +ActiveModel::Type+ that encrypts/decrypts strings of text.
5
+ # An ActiveModel::Type::Value that encrypts/decrypts strings of text.
6
6
  #
7
7
  # This is the central piece that connects the encryption system with +encrypts+ declarations in the
8
8
  # model classes. Whenever you declare an attribute as encrypted, it configures an +EncryptedAttributeType+
@@ -19,7 +19,7 @@ module ActiveRecord
19
19
  #
20
20
  # * <tt>:scheme</tt> - A +Scheme+ with the encryption properties for this attribute.
21
21
  # * <tt>:cast_type</tt> - A type that will be used to serialize (before encrypting) and deserialize
22
- # (after decrypting). +ActiveModel::Type::String+ by default.
22
+ # (after decrypting). ActiveModel::Type::String by default.
23
23
  def initialize(scheme:, cast_type: ActiveModel::Type::String.new, previous_type: false)
24
24
  super()
25
25
  @scheme = scheme
@@ -6,17 +6,17 @@ require "active_support/core_ext/numeric"
6
6
 
7
7
  module ActiveRecord
8
8
  module Encryption
9
- # An encryptor exposes the encryption API that +ActiveRecord::Encryption::EncryptedAttributeType+
9
+ # An encryptor exposes the encryption API that ActiveRecord::Encryption::EncryptedAttributeType
10
10
  # uses for encrypting and decrypting attribute values.
11
11
  #
12
- # It interacts with a +KeyProvider+ for getting the keys, and delegate to
13
- # +ActiveRecord::Encryption::Cipher+ the actual encryption algorithm.
12
+ # It interacts with a KeyProvider for getting the keys, and delegate to
13
+ # ActiveRecord::Encryption::Cipher the actual encryption algorithm.
14
14
  class Encryptor
15
15
  # Encrypts +clean_text+ and returns the encrypted result
16
16
  #
17
17
  # Internally, it will:
18
18
  #
19
- # 1. Create a new +ActiveRecord::Encryption::Message+
19
+ # 1. Create a new ActiveRecord::Encryption::Message
20
20
  # 2. Compress and encrypt +clean_text+ as the message payload
21
21
  # 3. Serialize it with +ActiveRecord::Encryption.message_serializer+ (+ActiveRecord::Encryption::SafeMarshal+
22
22
  # by default)
@@ -26,10 +26,10 @@ module ActiveRecord
26
26
  #
27
27
  # [:key_provider]
28
28
  # Key provider to use for the encryption operation. It will default to
29
- # +ActiveRecord::Encryption.key_provider+ when not provided
29
+ # +ActiveRecord::Encryption.key_provider+ when not provided.
30
30
  #
31
31
  # [:cipher_options]
32
- # +Cipher+-specific options that will be passed to the Cipher configured in
32
+ # Cipher-specific options that will be passed to the Cipher configured in
33
33
  # +ActiveRecord::Encryption.cipher+
34
34
  def encrypt(clear_text, key_provider: default_key_provider, cipher_options: {})
35
35
  clear_text = force_encoding_if_needed(clear_text) if cipher_options[:deterministic]
@@ -47,7 +47,7 @@ module ActiveRecord
47
47
  # +ActiveRecord::Encryption.key_provider+ when not provided
48
48
  #
49
49
  # [:cipher_options]
50
- # +Cipher+-specific options that will be passed to the Cipher configured in
50
+ # Cipher-specific options that will be passed to the Cipher configured in
51
51
  # +ActiveRecord::Encryption.cipher+
52
52
  def decrypt(encrypted_text, key_provider: default_key_provider, cipher_options: {})
53
53
  message = deserialize_message(encrypted_text)
@@ -4,13 +4,13 @@ module ActiveRecord
4
4
  module Encryption
5
5
  # Implements a simple envelope encryption approach where:
6
6
  #
7
- # * It generates a random data-encryption key for each encryption operation
7
+ # * It generates a random data-encryption key for each encryption operation.
8
8
  # * It stores the generated key along with the encrypted payload. It encrypts this key
9
- # with the master key provided in the credential +active_record.encryption.master key+
9
+ # with the master key provided in the +active_record_encryption.primary_key+ credential.
10
10
  #
11
11
  # This provider can work with multiple master keys. It will use the last one for encrypting.
12
12
  #
13
- # When `config.store_key_references` is true, it will also store a reference to
13
+ # When +config.active_record.encryption.store_key_references+ is true, it will also store a reference to
14
14
  # the specific master key that was used to encrypt the data-encryption key. When not set,
15
15
  # it will try all the configured master keys looking for the right one, in order to
16
16
  # return the right decryption key.
@@ -4,7 +4,7 @@ module ActiveRecord
4
4
  module Encryption
5
5
  # Automatically expand encrypted arguments to support querying both encrypted and unencrypted data
6
6
  #
7
- # Active Record Encryption supports querying the db using deterministic attributes. For example:
7
+ # Active Record \Encryption supports querying the db using deterministic attributes. For example:
8
8
  #
9
9
  # Contact.find_by(email_address: "jorge@hey.com")
10
10
  #
@@ -16,10 +16,10 @@ module ActiveRecord
16
16
  #
17
17
  # This patches ActiveRecord to support this automatically. It addresses both:
18
18
  #
19
- # * ActiveRecord::Base: Used in +Contact.find_by_email_address(...)+
20
- # * ActiveRecord::Relation: Used in +Contact.internal.find_by_email_address(...)+
19
+ # * ActiveRecord::Base - Used in <tt>Contact.find_by_email_address(...)</tt>
20
+ # * ActiveRecord::Relation - Used in <tt>Contact.internal.find_by_email_address(...)</tt>
21
21
  #
22
- # +ActiveRecord::Base+ relies on +ActiveRecord::Relation+ (+ActiveRecord::QueryMethods+) but it does
22
+ # ActiveRecord::Base relies on ActiveRecord::Relation (ActiveRecord::QueryMethods) but it does
23
23
  # some prepared statements caching. That's why we need to intercept +ActiveRecord::Base+ as soon
24
24
  # as it's invoked (so that the proper prepared statement is cached).
25
25
  #
@@ -6,7 +6,7 @@ module ActiveRecord
6
6
  #
7
7
  # It validates and serves attribute encryption options.
8
8
  #
9
- # See +EncryptedAttributeType+, +Context+
9
+ # See EncryptedAttributeType, Context
10
10
  class Scheme
11
11
  attr_accessor :previous_schemes
12
12
 
@@ -83,7 +83,7 @@ module ActiveRecord
83
83
  #
84
84
  # In rare circumstances you might need to access the mapping directly.
85
85
  # The mappings are exposed through a class method with the pluralized attribute
86
- # name, which return the mapping in a +HashWithIndifferentAccess+:
86
+ # name, which return the mapping in a ActiveSupport::HashWithIndifferentAccess :
87
87
  #
88
88
  # Conversation.statuses[:active] # => 0
89
89
  # Conversation.statuses["archived"] # => 1
@@ -241,13 +241,13 @@ module ActiveRecord
241
241
  # The generated ID for a given label is constant, so we can discover
242
242
  # any fixture's ID without loading anything, as long as we know the label.
243
243
  #
244
- # == Label references for associations (belongs_to, has_one, has_many)
244
+ # == Label references for associations (+belongs_to+, +has_one+, +has_many+)
245
245
  #
246
246
  # Specifying foreign keys in fixtures can be very fragile, not to
247
247
  # mention difficult to read. Since Active Record can figure out the ID of
248
248
  # any fixture from its label, you can specify FK's by label instead of ID.
249
249
  #
250
- # === belongs_to
250
+ # === +belongs_to+
251
251
  #
252
252
  # Let's break out some more monkeys and pirates.
253
253
  #
@@ -286,7 +286,7 @@ module ActiveRecord
286
286
  # a target *label* for the *association* (monkey: george) rather than
287
287
  # a target *id* for the *FK* (<tt>monkey_id: 1</tt>).
288
288
  #
289
- # ==== Polymorphic belongs_to
289
+ # ==== Polymorphic +belongs_to+
290
290
  #
291
291
  # Supporting polymorphic relationships is a little bit more complicated, since
292
292
  # Active Record needs to know what type your association is pointing at. Something
@@ -311,7 +311,7 @@ module ActiveRecord
311
311
  #
312
312
  # Just provide the polymorphic target type and Active Record will take care of the rest.
313
313
  #
314
- # === has_and_belongs_to_many or has_many :through
314
+ # === +has_and_belongs_to_many+ or <tt>has_many :through</tt>
315
315
  #
316
316
  # Time to give our monkey some fruit.
317
317
  #
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
- # Returns the version of the currently loaded Active Record as a <tt>Gem::Version</tt>
4
+ # Returns the currently loaded version of Active Record as a <tt>Gem::Version</tt>.
5
5
  def self.gem_version
6
6
  Gem::Version.new VERSION::STRING
7
7
  end
@@ -9,8 +9,8 @@ module ActiveRecord
9
9
  module VERSION
10
10
  MAJOR = 7
11
11
  MINOR = 0
12
- TINY = 2
13
- PRE = "3"
12
+ TINY = 3
13
+ PRE = "1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -5,7 +5,7 @@ module ActiveRecord
5
5
  # Locking::Pessimistic provides support for row-level locking using
6
6
  # SELECT ... FOR UPDATE and other lock types.
7
7
  #
8
- # Chain <tt>ActiveRecord::Base#find</tt> to <tt>ActiveRecord::QueryMethods#lock</tt> to obtain an exclusive
8
+ # Chain <tt>ActiveRecord::Base#find</tt> to ActiveRecord::QueryMethods#lock to obtain an exclusive
9
9
  # lock on the selected rows:
10
10
  # # select * from accounts where id=1 for update
11
11
  # Account.lock.find(1)
@@ -81,11 +81,11 @@ module ActiveRecord
81
81
 
82
82
  # Wraps the passed block in a transaction, locking the object
83
83
  # before yielding. You can pass the SQL locking clause
84
- # as an optional argument (see <tt>#lock!</tt>).
84
+ # as an optional argument (see #lock!).
85
85
  #
86
86
  # You can also pass options like <tt>requires_new:</tt>, <tt>isolation:</tt>,
87
87
  # and <tt>joinable:</tt> to the wrapping transaction (see
88
- # <tt>ActiveRecord::ConnectionAdapters::DatabaseStatements#transaction</tt>).
88
+ # ActiveRecord::ConnectionAdapters::DatabaseStatements#transaction).
89
89
  def with_lock(*args)
90
90
  transaction_opts = args.extract_options!
91
91
  lock = args.present? ? args.first : true
@@ -22,10 +22,8 @@ module ActiveRecord
22
22
  def strict_loading_violation(event)
23
23
  debug do
24
24
  owner = event.payload[:owner]
25
- association = event.payload[:reflection].klass
26
- name = event.payload[:reflection].name
27
-
28
- color("Strict loading violation: #{owner} is marked for strict loading. The #{association} association named :#{name} cannot be lazily loaded.", RED)
25
+ reflection = event.payload[:reflection]
26
+ color(reflection.strict_loading_violation_message(owner), RED)
29
27
  end
30
28
  end
31
29
 
@@ -51,7 +49,14 @@ module ActiveRecord
51
49
 
52
50
  binds = []
53
51
  payload[:binds].each_with_index do |attr, i|
54
- attribute_name = attr.respond_to?(:name) ? attr.name : attr[i].name
52
+ attribute_name = if attr.respond_to?(:name)
53
+ attr.name
54
+ elsif attr.respond_to?(:[]) && attr[i].respond_to?(:name)
55
+ attr[i].name
56
+ else
57
+ nil
58
+ end
59
+
55
60
  filtered_params = filter(attribute_name, casted_params[i])
56
61
 
57
62
  binds << render_bind(attr, filtered_params)
@@ -19,19 +19,22 @@ module ActiveRecord
19
19
  # that informs the application when to read from a primary or read from a
20
20
  # replica.
21
21
  #
22
- # To use the DatabaseSelector in your application with default settings add
23
- # the following options to your environment config:
22
+ # To use the DatabaseSelector in your application with default settings,
23
+ # run the provided generator.
24
24
  #
25
- # # This require is only necessary when using `rails new app --minimal`
26
- # require "active_support/core_ext/integer/time"
25
+ # bin/rails g active_record:multi_db
27
26
  #
28
- # class Application < Rails::Application
27
+ # This will create a file named +config/initializers/multi_db.rb+ with the
28
+ # following contents:
29
+ #
30
+ # Rails.application.configure do
29
31
  # config.active_record.database_selector = { delay: 2.seconds }
30
32
  # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
31
33
  # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
32
34
  # end
33
35
  #
34
- # New applications will include these lines commented out in the production.rb.
36
+ # Alternatively you can set the options in your environment config or
37
+ # any other config file loaded on boot.
35
38
  #
36
39
  # The default behavior can be changed by setting the config options to a
37
40
  # custom class:
@@ -39,6 +42,10 @@ module ActiveRecord
39
42
  # config.active_record.database_selector = { delay: 2.seconds }
40
43
  # config.active_record.database_resolver = MyResolver
41
44
  # config.active_record.database_resolver_context = MyResolver::MySession
45
+ #
46
+ # Note: If you are using `rails new my_app --minimal` you will need to call
47
+ # `require "active_support/core_ext/integer/time"` to load the libaries
48
+ # for +Time+.
42
49
  class DatabaseSelector
43
50
  def initialize(app, resolver_klass = nil, context_klass = nil, options = {})
44
51
  @app = app
@@ -7,11 +7,11 @@ module ActiveRecord
7
7
  # shard to switch to and allows for applications to write custom strategies
8
8
  # for swapping if needed.
9
9
  #
10
- # The ShardSelector takes a set of options (currently only `lock` is supported)
11
- # that can be used by the middleware to alter behavior. `lock` is
10
+ # The ShardSelector takes a set of options (currently only +lock+ is supported)
11
+ # that can be used by the middleware to alter behavior. +lock+ is
12
12
  # true by default and will prohibit the request from switching shards once
13
- # inside the block. If `lock` is false, then shard swapping will be allowed.
14
- # For tenant based sharding, `lock` should always be true to prevent application
13
+ # inside the block. If +lock+ is false, then shard swapping will be allowed.
14
+ # For tenant based sharding, +lock+ should always be true to prevent application
15
15
  # code from mistakenly switching between tenants.
16
16
  #
17
17
  # Options can be set in the config:
@@ -13,10 +13,10 @@ module ActiveRecord
13
13
  # * add_reference
14
14
  # * add_timestamps
15
15
  # * change_column
16
- # * change_column_default (must supply a :from and :to option)
16
+ # * change_column_default (must supply a +:from+ and +:to+ option)
17
17
  # * change_column_null
18
- # * change_column_comment (must supply a :from and :to option)
19
- # * change_table_comment (must supply a :from and :to option)
18
+ # * change_column_comment (must supply a +:from+ and +:to+ option)
19
+ # * change_table_comment (must supply a +:from+ and +:to+ option)
20
20
  # * create_join_table
21
21
  # * create_table
22
22
  # * disable_extension
@@ -92,27 +92,10 @@ module ActiveRecord
92
92
  end
93
93
  end
94
94
 
95
- module SQLite3
96
- module TableDefinition
97
- def references(*args, **options)
98
- args.each do |ref_name|
99
- ReferenceDefinition.new(ref_name, type: :integer, **options).add_to(self)
100
- end
101
- end
102
- alias :belongs_to :references
103
-
104
- def column(name, type, index: nil, **options)
105
- options[:precision] ||= nil
106
- super
107
- end
108
- end
109
- end
110
-
111
95
  module TableDefinition
112
96
  def references(*args, **options)
113
- args.each do |ref_name|
114
- ReferenceDefinition.new(ref_name, **options).add_to(self)
115
- end
97
+ options[:_uses_legacy_reference_index_name] = true
98
+ super
116
99
  end
117
100
  alias :belongs_to :references
118
101
 
@@ -148,12 +131,11 @@ module ActiveRecord
148
131
 
149
132
  def add_reference(table_name, ref_name, **options)
150
133
  if connection.adapter_name == "SQLite"
151
- reference_definition = ReferenceDefinition.new(ref_name, type: :integer, **options)
152
- else
153
- reference_definition = ReferenceDefinition.new(ref_name, **options)
134
+ options[:type] = :integer
154
135
  end
155
136
 
156
- reference_definition.add_to(connection.update_table_definition(table_name, self))
137
+ options[:_uses_legacy_reference_index_name] = true
138
+ super
157
139
  end
158
140
  alias :add_belongs_to :add_reference
159
141
 
@@ -161,9 +143,8 @@ module ActiveRecord
161
143
  def compatible_table_definition(t)
162
144
  class << t
163
145
  prepend TableDefinition
164
- prepend SQLite3::TableDefinition
165
146
  end
166
- t
147
+ super
167
148
  end
168
149
  end
169
150
 
@@ -228,7 +209,7 @@ module ActiveRecord
228
209
  class << t
229
210
  prepend TableDefinition
230
211
  end
231
- t
212
+ super
232
213
  end
233
214
 
234
215
  def command_recorder
@@ -326,7 +326,7 @@ module ActiveRecord
326
326
  # details.
327
327
  # * <tt>change_table(name, options)</tt>: Allows to make column alterations to
328
328
  # the table called +name+. It makes the table object available to a block that
329
- # can then add/remove columns, indexes or foreign keys to it.
329
+ # can then add/remove columns, indexes, or foreign keys to it.
330
330
  # * <tt>rename_column(table_name, column_name, new_column_name)</tt>: Renames
331
331
  # a column but keeps the type and content.
332
332
  # * <tt>rename_index(table_name, old_name, new_name)</tt>: Renames an index.
@@ -576,7 +576,7 @@ module ActiveRecord
576
576
  MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
577
577
 
578
578
  # This class is used to verify that all migrations have been run before
579
- # loading a web page if <tt>config.active_record.migration_error</tt> is set to :page_load
579
+ # loading a web page if <tt>config.active_record.migration_error</tt> is set to +:page_load+.
580
580
  class CheckPending
581
581
  def initialize(app, file_watcher: ActiveSupport::FileUpdateChecker)
582
582
  @app = app
@@ -810,8 +810,9 @@ module ActiveRecord
810
810
 
811
811
  # Runs the given migration classes.
812
812
  # Last argument can specify options:
813
- # - :direction (default is :up)
814
- # - :revert (default is false)
813
+ #
814
+ # - +:direction+ - Default is +:up+.
815
+ # - +:revert+ - Default is +false+.
815
816
  def run(*migration_classes)
816
817
  opts = migration_classes.extract_options!
817
818
  dir = opts[:direction] || :up
@@ -617,7 +617,7 @@ module ActiveRecord
617
617
 
618
618
  "#{full_table_name_prefix}#{contained}#{undecorated_table_name(model_name)}#{full_table_name_suffix}"
619
619
  else
620
- # STI subclasses always use their superclass' table.
620
+ # STI subclasses always use their superclass's table.
621
621
  base_class.table_name
622
622
  end
623
623
  end
@@ -62,7 +62,7 @@ module ActiveRecord
62
62
  # Active Record callbacks or validations. Though passed values
63
63
  # go through Active Record's type casting and serialization.
64
64
  #
65
- # See <tt>ActiveRecord::Persistence#insert_all</tt> for documentation.
65
+ # See #insert_all for documentation.
66
66
  def insert(attributes, returning: nil, unique_by: nil, record_timestamps: nil)
67
67
  insert_all([ attributes ], returning: returning, unique_by: unique_by, record_timestamps: record_timestamps)
68
68
  end
@@ -79,7 +79,7 @@ module ActiveRecord
79
79
  # duplicate rows are skipped.
80
80
  # Override with <tt>:unique_by</tt> (see below).
81
81
  #
82
- # Returns an <tt>ActiveRecord::Result</tt> with its contents based on
82
+ # Returns an ActiveRecord::Result with its contents based on
83
83
  # <tt>:returning</tt> (see below).
84
84
  #
85
85
  # ==== Options
@@ -151,7 +151,7 @@ module ActiveRecord
151
151
  # Active Record callbacks or validations. Though passed values
152
152
  # go through Active Record's type casting and serialization.
153
153
  #
154
- # See <tt>ActiveRecord::Persistence#insert_all!</tt> for more.
154
+ # See #insert_all! for more.
155
155
  def insert!(attributes, returning: nil, record_timestamps: nil)
156
156
  insert_all!([ attributes ], returning: returning, record_timestamps: record_timestamps)
157
157
  end
@@ -167,10 +167,9 @@ module ActiveRecord
167
167
  # Raises <tt>ActiveRecord::RecordNotUnique</tt> if any rows violate a
168
168
  # unique index on the table. In that case, no rows are inserted.
169
169
  #
170
- # To skip duplicate rows, see <tt>ActiveRecord::Persistence#insert_all</tt>.
171
- # To replace them, see <tt>ActiveRecord::Persistence#upsert_all</tt>.
170
+ # To skip duplicate rows, see #insert_all. To replace them, see #upsert_all.
172
171
  #
173
- # Returns an <tt>ActiveRecord::Result</tt> with its contents based on
172
+ # Returns an ActiveRecord::Result with its contents based on
174
173
  # <tt>:returning</tt> (see below).
175
174
  #
176
175
  # ==== Options
@@ -219,7 +218,7 @@ module ActiveRecord
219
218
  # it trigger Active Record callbacks or validations. Though passed values
220
219
  # go through Active Record's type casting and serialization.
221
220
  #
222
- # See <tt>ActiveRecord::Persistence#upsert_all</tt> for documentation.
221
+ # See #upsert_all for documentation.
223
222
  def upsert(attributes, on_duplicate: :update, returning: nil, unique_by: nil, record_timestamps: nil)
224
223
  upsert_all([ attributes ], on_duplicate: on_duplicate, returning: returning, unique_by: unique_by, record_timestamps: record_timestamps)
225
224
  end
@@ -232,7 +231,7 @@ module ActiveRecord
232
231
  # The +attributes+ parameter is an Array of Hashes. Every Hash determines
233
232
  # the attributes for a single row and must have the same keys.
234
233
  #
235
- # Returns an <tt>ActiveRecord::Result</tt> with its contents based on
234
+ # Returns an ActiveRecord::Result with its contents based on
236
235
  # <tt>:returning</tt> (see below).
237
236
  #
238
237
  # By default, +upsert_all+ will update all the columns that can be updated when
@@ -806,6 +805,7 @@ module ActiveRecord
806
805
  def update_columns(attributes)
807
806
  raise ActiveRecordError, "cannot update a new record" if new_record?
808
807
  raise ActiveRecordError, "cannot update a destroyed record" if destroyed?
808
+ _raise_readonly_record_error if readonly?
809
809
 
810
810
  attributes = attributes.transform_keys do |key|
811
811
  name = key.to_s
@@ -992,6 +992,7 @@ module ActiveRecord
992
992
  #
993
993
  def touch(*names, time: nil)
994
994
  _raise_record_not_touched_error unless persisted?
995
+ _raise_readonly_record_error if readonly?
995
996
 
996
997
  attribute_names = timestamp_attributes_for_update_in_model
997
998
  attribute_names |= names.map! do |name|
@@ -39,7 +39,7 @@ module ActiveRecord
39
39
  # Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
40
40
  # # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "author"=>"Quentin"}>, ...]
41
41
  #
42
- # You can use the same string replacement techniques as you can with <tt>ActiveRecord::QueryMethods#where</tt>:
42
+ # You can use the same string replacement techniques as you can with ActiveRecord::QueryMethods#where :
43
43
  #
44
44
  # Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
45
45
  # Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
@@ -389,5 +389,37 @@ To keep using the current cache store, you can turn off cache versioning entirel
389
389
  end
390
390
  end
391
391
  end
392
+
393
+ initializer "active_record.unregister_current_scopes_on_unload" do |app|
394
+ config.after_initialize do
395
+ unless app.config.cache_classes
396
+ Rails.autoloaders.main.on_unload do |_cpath, value, _abspath|
397
+ # Conditions are written this way to be robust against custom
398
+ # implementations of value#is_a? or value#<.
399
+ if Class === value && ActiveRecord::Base > value
400
+ value.current_scope = nil
401
+ end
402
+ end
403
+ end
404
+ end
405
+ end
406
+
407
+ initializer "active_record.use_yaml_unsafe_load" do |app|
408
+ config.after_initialize do
409
+ unless app.config.active_record.use_yaml_unsafe_load.nil?
410
+ ActiveRecord.use_yaml_unsafe_load =
411
+ app.config.active_record.use_yaml_unsafe_load
412
+ end
413
+ end
414
+ end
415
+
416
+ initializer "active_record.yaml_column_permitted_classes" do |app|
417
+ config.after_initialize do
418
+ unless app.config.active_record.yaml_column_permitted_classes.nil?
419
+ ActiveRecord.yaml_column_permitted_classes =
420
+ app.config.active_record.yaml_column_permitted_classes
421
+ end
422
+ end
423
+ end
392
424
  end
393
425
  end
@@ -484,7 +484,7 @@ db_namespace = namespace :db do
484
484
  namespace :load do
485
485
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
486
486
  desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the #{name} database"
487
- task name => :load_config do
487
+ task name => [:load_config, :check_protected_environments] do
488
488
  original_db_config = ActiveRecord::Base.connection_db_config
489
489
  db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
490
490
  ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config)
@@ -297,6 +297,12 @@ module ActiveRecord
297
297
  options[:strict_loading]
298
298
  end
299
299
 
300
+ def strict_loading_violation_message(owner)
301
+ message = +"`#{owner}` is marked for strict_loading."
302
+ message << " The #{polymorphic? ? "polymorphic association" : "#{klass} association"}"
303
+ message << " named `:#{name}` cannot be lazily loaded."
304
+ end
305
+
300
306
  protected
301
307
  def actual_source_reflection # FIXME: this is a horrible name
302
308
  self
@@ -37,7 +37,7 @@ module ActiveRecord
37
37
  # * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
38
38
  # * <tt>:error_on_ignore</tt> - Overrides the application config to specify if an error should be raised when
39
39
  # an order is present in the relation.
40
- # * <tt>:order</tt> - Specifies the primary key order (can be :asc or :desc). Defaults to :asc.
40
+ # * <tt>:order</tt> - Specifies the primary key order (can be +:asc+ or +:desc+). Defaults to +:asc+.
41
41
  #
42
42
  # Limits are honored, and if present there is no requirement for the batch
43
43
  # size: it can be less than, equal to, or greater than the limit.
@@ -102,7 +102,7 @@ module ActiveRecord
102
102
  # * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
103
103
  # * <tt>:error_on_ignore</tt> - Overrides the application config to specify if an error should be raised when
104
104
  # an order is present in the relation.
105
- # * <tt>:order</tt> - Specifies the primary key order (can be :asc or :desc). Defaults to :asc.
105
+ # * <tt>:order</tt> - Specifies the primary key order (can be +:asc+ or +:desc+). Defaults to +:asc+.
106
106
  #
107
107
  # Limits are honored, and if present there is no requirement for the batch
108
108
  # size: it can be less than, equal to, or greater than the limit.
@@ -167,7 +167,7 @@ module ActiveRecord
167
167
  # * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
168
168
  # * <tt>:error_on_ignore</tt> - Overrides the application config to specify if an error should be raised when
169
169
  # an order is present in the relation.
170
- # * <tt>:order</tt> - Specifies the primary key order (can be :asc or :desc). Defaults to :asc.
170
+ # * <tt>:order</tt> - Specifies the primary key order (can be +:asc+ or +:desc+). Defaults to +:asc+.
171
171
  #
172
172
  # Limits are honored, and if present there is no requirement for the batch
173
173
  # size, it can be less than, equal, or greater than the limit.
@@ -40,6 +40,13 @@ module ActiveRecord
40
40
  #
41
41
  # User.where.not(name: "Jon", role: "admin")
42
42
  # # SELECT * FROM users WHERE NOT (name == 'Jon' AND role == 'admin')
43
+ #
44
+ # If there is a non-nil condition on a nullable column in the hash condition, the records that have
45
+ # nil values on the nullable column won't be returned.
46
+ # User.create!(nullable_country: nil)
47
+ # User.where.not(nullable_country: "UK")
48
+ # # SELECT * FROM users WHERE NOT (nullable_country = 'UK')
49
+ # # => []
43
50
  def not(opts, *rest)
44
51
  where_clause = @scope.send(:build_where_clause, opts, rest)
45
52
 
@@ -162,7 +169,7 @@ module ActiveRecord
162
169
  #
163
170
  # users = User.includes(:address, friends: [:address, :followers])
164
171
  #
165
- # === conditions
172
+ # === Conditions
166
173
  #
167
174
  # If you want to add string conditions to your included models, you'll have
168
175
  # to explicitly reference them. For example: