activerecord 7.0.2.3 → 7.0.3.1
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.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +80 -0
- data/lib/active_record/associations/collection_association.rb +1 -1
- data/lib/active_record/associations/collection_proxy.rb +1 -1
- data/lib/active_record/associations.rb +9 -9
- data/lib/active_record/attribute_methods/serialization.rb +34 -50
- data/lib/active_record/attribute_methods.rb +1 -1
- data/lib/active_record/base.rb +3 -3
- data/lib/active_record/coders/yaml_column.rb +9 -7
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +4 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +3 -3
- data/lib/active_record/connection_adapters/abstract_adapter.rb +5 -5
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +4 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +3 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +19 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +3 -3
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +1 -1
- data/lib/active_record/connection_handling.rb +2 -2
- data/lib/active_record/core.rb +3 -3
- data/lib/active_record/encryption/configurable.rb +8 -2
- data/lib/active_record/encryption/contexts.rb +3 -3
- data/lib/active_record/encryption/derived_secret_key_provider.rb +1 -1
- data/lib/active_record/encryption/deterministic_key_provider.rb +1 -1
- data/lib/active_record/encryption/encryptable_record.rb +2 -4
- data/lib/active_record/encryption/encrypted_attribute_type.rb +2 -2
- 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 +4 -4
- data/lib/active_record/encryption/scheme.rb +1 -1
- data/lib/active_record/enum.rb +1 -1
- data/lib/active_record/fixtures.rb +4 -4
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +10 -5
- data/lib/active_record/middleware/database_selector.rb +13 -6
- data/lib/active_record/middleware/shard_selector.rb +4 -4
- data/lib/active_record/migration/command_recorder.rb +3 -3
- data/lib/active_record/migration/compatibility.rb +7 -26
- data/lib/active_record/migration.rb +5 -4
- data/lib/active_record/model_schema.rb +1 -1
- data/lib/active_record/persistence.rb +9 -8
- data/lib/active_record/querying.rb +1 -1
- data/lib/active_record/railtie.rb +32 -0
- data/lib/active_record/railties/databases.rake +1 -1
- data/lib/active_record/reflection.rb +6 -0
- data/lib/active_record/relation/batches.rb +3 -3
- data/lib/active_record/relation/query_methods.rb +8 -1
- data/lib/active_record/relation.rb +6 -6
- data/lib/active_record/sanitization.rb +6 -5
- data/lib/active_record/scoping/default.rb +1 -5
- data/lib/active_record/serialization.rb +5 -0
- data/lib/active_record/signed_id.rb +1 -1
- data/lib/active_record/tasks/database_tasks.rb +26 -21
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -2
- data/lib/active_record/test_fixtures.rb +3 -0
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/validations/associated.rb +3 -3
- data/lib/active_record/validations/presence.rb +2 -2
- data/lib/active_record/validations/uniqueness.rb +3 -3
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +14 -0
- metadata +10 -10
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3f2f45fa92947b78ba64cfc800a729cfcab5b893255efef679b686a37c50cd00
         | 
| 4 | 
            +
              data.tar.gz: 2bcca713bf8426cf4ffd22e1b832cde62a6cd6caad0f1f9b19996916e88922d5
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 17fdc443b9f36e8dcba05e56b6c07e88e97266f7c12accb8ac084b37dbf2c134a696fc57b71171fc488ed10fc72fba952672960b7507d14762a1a41f25623df1
         | 
| 7 | 
            +
              data.tar.gz: 4dc59bd725e08e3cdf63d5145f2038f6e5c65b5eb40e611a18ef422c516543aa2acfbc893b68f25f39d304111bafd70a131928c4c1e0692e4274e5fdb1567e53
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,83 @@ | |
| 1 | 
            +
            ## Rails 7.0.3.1 (July 12, 2022) ##
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            *   Change ActiveRecord::Coders::YAMLColumn default to safe_load
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                This adds two new configuration options The configuration options are as
         | 
| 6 | 
            +
                follows:
         | 
| 7 | 
            +
                
         | 
| 8 | 
            +
                * `config.active_storage.use_yaml_unsafe_load`
         | 
| 9 | 
            +
                
         | 
| 10 | 
            +
                When set to true, this configuration option tells Rails to use the old
         | 
| 11 | 
            +
                "unsafe" YAML loading strategy, maintaining the existing behavior but leaving
         | 
| 12 | 
            +
                the possible escalation vulnerability in place.  Setting this option to true
         | 
| 13 | 
            +
                is *not* recommended, but can aid in upgrading.
         | 
| 14 | 
            +
                
         | 
| 15 | 
            +
                * `config.active_record.yaml_column_permitted_classes`
         | 
| 16 | 
            +
                
         | 
| 17 | 
            +
                The "safe YAML" loading method does not allow all classes to be deserialized
         | 
| 18 | 
            +
                by default.  This option allows you to specify classes deemed "safe" in your
         | 
| 19 | 
            +
                application.  For example, if your application uses Symbol and Time in
         | 
| 20 | 
            +
                serialized data, you can add Symbol and Time to the allowed list as follows:
         | 
| 21 | 
            +
                
         | 
| 22 | 
            +
                ```
         | 
| 23 | 
            +
                config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
         | 
| 24 | 
            +
                ```
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                [CVE-2022-32224]
         | 
| 27 | 
            +
             | 
| 28 | 
            +
             | 
| 29 | 
            +
            ## Rails 7.0.3 (May 09, 2022) ##
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            *   Some internal housekeeping on reloads could break custom `respond_to?`
         | 
| 32 | 
            +
                methods in class objects that referenced reloadable constants. See
         | 
| 33 | 
            +
                [#44125](https://github.com/rails/rails/issues/44125) for details.
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                *Xavier Noria*
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            *   Fixed MariaDB default function support.
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                Defaults would be written wrong in "db/schema.rb" and not work correctly
         | 
| 40 | 
            +
                if using `db:schema:load`. Further more the function name would be
         | 
| 41 | 
            +
                added as string content when saving new records.
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                *kaspernj*
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            *   Fix `remove_foreign_key` with `:if_exists` option when foreign key actually exists.
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                *fatkodima*
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            *   Remove `--no-comments` flag in structure dumps for PostgreSQL
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                This broke some apps that used custom schema comments. If you don't want
         | 
| 52 | 
            +
                comments in your structure dump, you can use:
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                ```ruby
         | 
| 55 | 
            +
                ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-comments']
         | 
| 56 | 
            +
                ```
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                *Alex Ghiculescu*
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            *   Use the model name as a prefix when filtering encrypted attributes from logs.
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                For example, when encrypting `Person#name` it will add `person.name` as a filter
         | 
| 63 | 
            +
                parameter, instead of just `name`. This prevents unintended filtering of parameters
         | 
| 64 | 
            +
                with a matching name in other models.
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                *Jorge Manrubia*
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            *   Fix quoting of `ActiveSupport::Duration` and `Rational` numbers in the MySQL adapter.
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                *Kevin McPhillips*
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            *   Fix `change_column_comment` to preserve column's AUTO_INCREMENT in the MySQL adapter
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                *fatkodima*
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            ## Rails 7.0.2.4 (April 26, 2022) ##
         | 
| 77 | 
            +
             | 
| 78 | 
            +
            *   No changes.
         | 
| 79 | 
            +
             | 
| 80 | 
            +
             | 
| 1 81 | 
             
            ## Rails 7.0.2.3 (March 08, 2022) ##
         | 
| 2 82 |  | 
| 3 83 | 
             
            *   No changes.
         | 
| @@ -180,7 +180,7 @@ module ActiveRecord | |
| 180 180 | 
             
                  end
         | 
| 181 181 |  | 
| 182 182 | 
             
                  # Deletes the +records+ and removes them from this association calling
         | 
| 183 | 
            -
                  # +before_remove | 
| 183 | 
            +
                  # +before_remove+, +after_remove+, +before_destroy+ and +after_destroy+ callbacks.
         | 
| 184 184 | 
             
                  #
         | 
| 185 185 | 
             
                  # Note that this method removes records from the database ignoring the
         | 
| 186 186 | 
             
                  # +:dependent+ option.
         | 
| @@ -475,7 +475,7 @@ module ActiveRecord | |
| 475 475 |  | 
| 476 476 | 
             
                  # Deletes the records of the collection directly from the database
         | 
| 477 477 | 
             
                  # ignoring the +:dependent+ option. Records are instantiated and it
         | 
| 478 | 
            -
                  # invokes +before_remove+, +after_remove | 
| 478 | 
            +
                  # invokes +before_remove+, +after_remove+, +before_destroy+, and
         | 
| 479 479 | 
             
                  # +after_destroy+ callbacks.
         | 
| 480 480 | 
             
                  #
         | 
| 481 481 | 
             
                  #   class Person < ActiveRecord::Base
         | 
| @@ -432,7 +432,7 @@ module ActiveRecord | |
| 432 432 | 
             
                  #
         | 
| 433 433 | 
             
                  # == Cardinality and associations
         | 
| 434 434 | 
             
                  #
         | 
| 435 | 
            -
                  # Active Record associations can be used to describe one-to-one, one-to-many and many-to-many
         | 
| 435 | 
            +
                  # Active Record associations can be used to describe one-to-one, one-to-many, and many-to-many
         | 
| 436 436 | 
             
                  # relationships between models. Each model uses an association to describe its role in
         | 
| 437 437 | 
             
                  # the relation. The #belongs_to association is always used in the model that has
         | 
| 438 438 | 
             
                  # the foreign key.
         | 
| @@ -586,7 +586,7 @@ module ActiveRecord | |
| 586 586 | 
             
                  #     has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
         | 
| 587 587 | 
             
                  #   end
         | 
| 588 588 | 
             
                  #
         | 
| 589 | 
            -
                  # Note: Joining, eager loading and preloading of these associations is not possible.
         | 
| 589 | 
            +
                  # Note: Joining, eager loading, and preloading of these associations is not possible.
         | 
| 590 590 | 
             
                  # These operations happen before instance creation and the scope will be called with a +nil+ argument.
         | 
| 591 591 | 
             
                  #
         | 
| 592 592 | 
             
                  # == Association callbacks
         | 
| @@ -618,7 +618,7 @@ module ActiveRecord | |
| 618 618 | 
             
                  #              after_remove: :log_after_remove
         | 
| 619 619 | 
             
                  #   end
         | 
| 620 620 | 
             
                  #
         | 
| 621 | 
            -
                  # Possible callbacks are: +before_add+, +after_add+, +before_remove | 
| 621 | 
            +
                  # Possible callbacks are: +before_add+, +after_add+, +before_remove+, and +after_remove+.
         | 
| 622 622 | 
             
                  #
         | 
| 623 623 | 
             
                  # If any of the +before_add+ callbacks throw an exception, the object will not be
         | 
| 624 624 | 
             
                  # added to the collection.
         | 
| @@ -1332,7 +1332,7 @@ module ActiveRecord | |
| 1332 1332 | 
             
                    # === Extensions
         | 
| 1333 1333 | 
             
                    #
         | 
| 1334 1334 | 
             
                    # The +extension+ argument allows you to pass a block into a has_many
         | 
| 1335 | 
            -
                    # association. This is useful for adding new finders, creators and other
         | 
| 1335 | 
            +
                    # association. This is useful for adding new finders, creators, and other
         | 
| 1336 1336 | 
             
                    # factory-type methods to be used as part of the association.
         | 
| 1337 1337 | 
             
                    #
         | 
| 1338 1338 | 
             
                    # Extension examples:
         | 
| @@ -1415,8 +1415,8 @@ module ActiveRecord | |
| 1415 1415 | 
             
                    # [:disable_joins]
         | 
| 1416 1416 | 
             
                    #   Specifies whether joins should be skipped for an association. If set to true, two or more queries
         | 
| 1417 1417 | 
             
                    #   will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
         | 
| 1418 | 
            -
                    #   due to database limitations. This option is only applicable on  | 
| 1419 | 
            -
                    #    | 
| 1418 | 
            +
                    #   due to database limitations. This option is only applicable on <tt>has_many :through</tt> associations as
         | 
| 1419 | 
            +
                    #   +has_many+ alone do not perform a join.
         | 
| 1420 1420 | 
             
                    # [:source]
         | 
| 1421 1421 | 
             
                    #   Specifies the source association name used by #has_many <tt>:through</tt> queries.
         | 
| 1422 1422 | 
             
                    #   Only use it if the name cannot be inferred from the association.
         | 
| @@ -1580,8 +1580,8 @@ module ActiveRecord | |
| 1580 1580 | 
             
                    # [:disable_joins]
         | 
| 1581 1581 | 
             
                    #   Specifies whether joins should be skipped for an association. If set to true, two or more queries
         | 
| 1582 1582 | 
             
                    #   will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
         | 
| 1583 | 
            -
                    #   due to database limitations. This option is only applicable on  | 
| 1584 | 
            -
                    #    | 
| 1583 | 
            +
                    #   due to database limitations. This option is only applicable on <tt>has_one :through</tt> associations as
         | 
| 1584 | 
            +
                    #   +has_one+ alone does not perform a join.
         | 
| 1585 1585 | 
             
                    # [:source]
         | 
| 1586 1586 | 
             
                    #   Specifies the source association name used by #has_one <tt>:through</tt> queries.
         | 
| 1587 1587 | 
             
                    #   Only use it if the name cannot be inferred from the association.
         | 
| @@ -1904,7 +1904,7 @@ module ActiveRecord | |
| 1904 1904 | 
             
                    #
         | 
| 1905 1905 | 
             
                    # The +extension+ argument allows you to pass a block into a
         | 
| 1906 1906 | 
             
                    # has_and_belongs_to_many association. This is useful for adding new
         | 
| 1907 | 
            -
                    # finders, creators and other factory-type methods to be used as part of
         | 
| 1907 | 
            +
                    # finders, creators, and other factory-type methods to be used as part of
         | 
| 1908 1908 | 
             
                    # the association.
         | 
| 1909 1909 | 
             
                    #
         | 
| 1910 1910 | 
             
                    # Extension examples:
         | 
| @@ -24,38 +24,6 @@ module ActiveRecord | |
| 24 24 | 
             
                    # The serialization format may be YAML, JSON, or any custom format using a
         | 
| 25 25 | 
             
                    # custom coder class.
         | 
| 26 26 | 
             
                    #
         | 
| 27 | 
            -
                    # === Serialization formats
         | 
| 28 | 
            -
                    #
         | 
| 29 | 
            -
                    #   serialize attr_name [, class_name_or_coder]
         | 
| 30 | 
            -
                    #
         | 
| 31 | 
            -
                    #                        |                           |  database storage   |
         | 
| 32 | 
            -
                    #   class_name_or_coder  | attribute read/write type | serialized | NULL   |
         | 
| 33 | 
            -
                    #   ---------------------+---------------------------+------------+--------+
         | 
| 34 | 
            -
                    #     <not given>        | any value that supports   |    YAML    |        |
         | 
| 35 | 
            -
                    #                        |   .to_yaml                |            |        |
         | 
| 36 | 
            -
                    #                        |                           |            |        |
         | 
| 37 | 
            -
                    #   Array                | Array **                  |    YAML    |  []    |
         | 
| 38 | 
            -
                    #                        |                           |            |        |
         | 
| 39 | 
            -
                    #   Hash                 | Hash **                   |    YAML    |  {}    |
         | 
| 40 | 
            -
                    #                        |                           |            |        |
         | 
| 41 | 
            -
                    #   JSON                 | any value that supports   |    JSON    |        |
         | 
| 42 | 
            -
                    #                        |   .to_json                |            |        |
         | 
| 43 | 
            -
                    #                        |                           |            |        |
         | 
| 44 | 
            -
                    #   <custom coder class> | any value supported by    |   custom   | custom |
         | 
| 45 | 
            -
                    #                        | the custom coder class    |            |        |
         | 
| 46 | 
            -
                    #
         | 
| 47 | 
            -
                    # ** If +class_name_or_coder+ is +Array+ or +Hash+, values retrieved will
         | 
| 48 | 
            -
                    # always be of that type, and any value assigned must be of that type or
         | 
| 49 | 
            -
                    # +SerializationTypeMismatch+ will be raised.
         | 
| 50 | 
            -
                    #
         | 
| 51 | 
            -
                    # ==== Custom coders
         | 
| 52 | 
            -
                    # A custom coder class or module may be given. This must have +self.load+
         | 
| 53 | 
            -
                    # and +self.dump+ class/module methods. <tt>self.dump(object)</tt> will be called
         | 
| 54 | 
            -
                    # to serialize an object and should return the serialized value to be
         | 
| 55 | 
            -
                    # stored in the database (+nil+ to store as +NULL+). <tt>self.load(string)</tt>
         | 
| 56 | 
            -
                    # will be called to reverse the process and load (unserialize) from the
         | 
| 57 | 
            -
                    # database.
         | 
| 58 | 
            -
                    #
         | 
| 59 27 | 
             
                    # Keep in mind that database adapters handle certain serialization tasks
         | 
| 60 28 | 
             
                    # for you. For instance: +json+ and +jsonb+ types in PostgreSQL will be
         | 
| 61 29 | 
             
                    # converted between JSON object/array syntax and Ruby +Hash+ or +Array+
         | 
| @@ -67,55 +35,71 @@ module ActiveRecord | |
| 67 35 | 
             
                    #
         | 
| 68 36 | 
             
                    # ==== Parameters
         | 
| 69 37 | 
             
                    #
         | 
| 70 | 
            -
                    # * +attr_name+ - The  | 
| 71 | 
            -
                    # * +class_name_or_coder+ - Optional | 
| 72 | 
            -
                    #    | 
| 73 | 
            -
                    # | 
| 38 | 
            +
                    # * +attr_name+ - The name of the attribute to serialize.
         | 
| 39 | 
            +
                    # * +class_name_or_coder+ - Optional. May be one of the following:
         | 
| 40 | 
            +
                    #   * <em>default</em> - The attribute value will be serialized as YAML.
         | 
| 41 | 
            +
                    #     The attribute value must respond to +to_yaml+.
         | 
| 42 | 
            +
                    #   * +Array+ - The attribute value will be serialized as YAML, but an
         | 
| 43 | 
            +
                    #     empty +Array+ will be serialized as +NULL+. The attribute value
         | 
| 44 | 
            +
                    #     must be an +Array+.
         | 
| 45 | 
            +
                    #   * +Hash+ - The attribute value will be serialized as YAML, but an
         | 
| 46 | 
            +
                    #     empty +Hash+ will be serialized as +NULL+. The attribute value
         | 
| 47 | 
            +
                    #     must be a +Hash+.
         | 
| 48 | 
            +
                    #   * +JSON+ - The attribute value will be serialized as JSON. The
         | 
| 49 | 
            +
                    #     attribute value must respond to +to_json+.
         | 
| 50 | 
            +
                    #   * <em>custom coder</em> - The attribute value will be serialized
         | 
| 51 | 
            +
                    #     using the coder's <tt>dump(value)</tt> method, and will be
         | 
| 52 | 
            +
                    #     deserialized using the coder's <tt>load(string)</tt> method. The
         | 
| 53 | 
            +
                    #     +dump+ method may return +nil+ to serialize the value as +NULL+.
         | 
| 74 54 | 
             
                    #
         | 
| 75 55 | 
             
                    # ==== Options
         | 
| 76 56 | 
             
                    #
         | 
| 77 | 
            -
                    #  | 
| 78 | 
            -
                    # is not passed, the previous default value (if any) will | 
| 79 | 
            -
                    # Otherwise, the default will be +nil+.
         | 
| 57 | 
            +
                    # * +:default+ - The default value to use when no value is provided. If
         | 
| 58 | 
            +
                    #   this option is not passed, the previous default value (if any) will
         | 
| 59 | 
            +
                    #   be used. Otherwise, the default will be +nil+.
         | 
| 60 | 
            +
                    #
         | 
| 61 | 
            +
                    # ==== Examples
         | 
| 80 62 | 
             
                    #
         | 
| 81 | 
            -
                    #  | 
| 63 | 
            +
                    # ===== Serialize the +preferences+ attribute using YAML
         | 
| 82 64 | 
             
                    #
         | 
| 83 | 
            -
                    #   # Serialize a preferences attribute using YAML coder.
         | 
| 84 65 | 
             
                    #   class User < ActiveRecord::Base
         | 
| 85 66 | 
             
                    #     serialize :preferences
         | 
| 86 67 | 
             
                    #   end
         | 
| 87 68 | 
             
                    #
         | 
| 88 | 
            -
                    # | 
| 69 | 
            +
                    # ===== Serialize the +preferences+ attribute using JSON
         | 
| 70 | 
            +
                    #
         | 
| 89 71 | 
             
                    #   class User < ActiveRecord::Base
         | 
| 90 72 | 
             
                    #     serialize :preferences, JSON
         | 
| 91 73 | 
             
                    #   end
         | 
| 92 74 | 
             
                    #
         | 
| 93 | 
            -
                    # | 
| 75 | 
            +
                    # ===== Serialize the +preferences+ +Hash+ using YAML
         | 
| 76 | 
            +
                    #
         | 
| 94 77 | 
             
                    #   class User < ActiveRecord::Base
         | 
| 95 78 | 
             
                    #     serialize :preferences, Hash
         | 
| 96 79 | 
             
                    #   end
         | 
| 97 80 | 
             
                    #
         | 
| 98 | 
            -
                    # | 
| 81 | 
            +
                    # ===== Serialize the +preferences+ attribute using a custom coder
         | 
| 82 | 
            +
                    #
         | 
| 99 83 | 
             
                    #   class Rot13JSON
         | 
| 100 84 | 
             
                    #     def self.rot13(string)
         | 
| 101 85 | 
             
                    #       string.tr("a-zA-Z", "n-za-mN-ZA-M")
         | 
| 102 86 | 
             
                    #     end
         | 
| 103 87 | 
             
                    #
         | 
| 104 | 
            -
                    #     #  | 
| 105 | 
            -
                    #     def self.dump( | 
| 106 | 
            -
                    #       ActiveSupport::JSON. | 
| 88 | 
            +
                    #     # Serializes an attribute value to a string that will be stored in the database.
         | 
| 89 | 
            +
                    #     def self.dump(value)
         | 
| 90 | 
            +
                    #       rot13(ActiveSupport::JSON.dump(value))
         | 
| 107 91 | 
             
                    #     end
         | 
| 108 92 | 
             
                    #
         | 
| 109 | 
            -
                    #     #  | 
| 110 | 
            -
                    #     # back into its original value
         | 
| 93 | 
            +
                    #     # Deserializes a string from the database to an attribute value.
         | 
| 111 94 | 
             
                    #     def self.load(string)
         | 
| 112 | 
            -
                    #       ActiveSupport::JSON. | 
| 95 | 
            +
                    #       ActiveSupport::JSON.load(rot13(string))
         | 
| 113 96 | 
             
                    #     end
         | 
| 114 97 | 
             
                    #   end
         | 
| 115 98 | 
             
                    #
         | 
| 116 99 | 
             
                    #   class User < ActiveRecord::Base
         | 
| 117 100 | 
             
                    #     serialize :preferences, Rot13JSON
         | 
| 118 101 | 
             
                    #   end
         | 
| 102 | 
            +
                    #
         | 
| 119 103 | 
             
                    def serialize(attr_name, class_name_or_coder = Object, **options)
         | 
| 120 104 | 
             
                      # When ::JSON is used, force it to go through the Active Support JSON encoder
         | 
| 121 105 | 
             
                      # to ensure special objects (e.g. Active Record models) are dumped correctly
         | 
| @@ -97,7 +97,7 @@ module ActiveRecord | |
| 97 97 | 
             
                      super
         | 
| 98 98 | 
             
                    else
         | 
| 99 99 | 
             
                      # If ThisClass < ... < SomeSuperClass < ... < Base and SomeSuperClass
         | 
| 100 | 
            -
                      # defines its own attribute method, then we don't want to  | 
| 100 | 
            +
                      # defines its own attribute method, then we don't want to override that.
         | 
| 101 101 | 
             
                      defined = method_defined_within?(method_name, superclass, Base) &&
         | 
| 102 102 | 
             
                        ! superclass.instance_method(method_name).owner.is_a?(GeneratedAttributeMethods)
         | 
| 103 103 | 
             
                      defined || super
         | 
    
        data/lib/active_record/base.rb
    CHANGED
    
    | @@ -137,7 +137,7 @@ module ActiveRecord # :nodoc: | |
| 137 137 | 
             
              #   anonymous = User.new(name: "")
         | 
| 138 138 | 
             
              #   anonymous.name? # => false
         | 
| 139 139 | 
             
              #
         | 
| 140 | 
            -
              # Query methods will also respect any  | 
| 140 | 
            +
              # Query methods will also respect any overrides of default accessors:
         | 
| 141 141 | 
             
              #
         | 
| 142 142 | 
             
              #   class User
         | 
| 143 143 | 
             
              #     # Has admin boolean column
         | 
| @@ -151,8 +151,8 @@ module ActiveRecord # :nodoc: | |
| 151 151 | 
             
              #   user.read_attribute(:admin)  # => true, gets the column value
         | 
| 152 152 | 
             
              #   user[:admin] # => true, also gets the column value
         | 
| 153 153 | 
             
              #
         | 
| 154 | 
            -
              #   user.admin   # => false, due to the getter  | 
| 155 | 
            -
              #   user.admin?  # => false, due to the getter  | 
| 154 | 
            +
              #   user.admin   # => false, due to the getter override
         | 
| 155 | 
            +
              #   user.admin?  # => false, due to the getter override
         | 
| 156 156 | 
             
              #
         | 
| 157 157 | 
             
              # == Accessing attributes before they have been typecasted
         | 
| 158 158 | 
             
              #
         | 
| @@ -45,13 +45,15 @@ module ActiveRecord | |
| 45 45 | 
             
                      raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
         | 
| 46 46 | 
             
                    end
         | 
| 47 47 |  | 
| 48 | 
            -
                     | 
| 49 | 
            -
                       | 
| 50 | 
            -
                        YAML. | 
| 51 | 
            -
                       | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
                         | 
| 48 | 
            +
                    def yaml_load(payload)
         | 
| 49 | 
            +
                      if !ActiveRecord.use_yaml_unsafe_load
         | 
| 50 | 
            +
                        YAML.safe_load(payload, permitted_classes: ActiveRecord.yaml_column_permitted_classes, aliases: true)
         | 
| 51 | 
            +
                      else
         | 
| 52 | 
            +
                        if YAML.respond_to?(:unsafe_load)
         | 
| 53 | 
            +
                          YAML.unsafe_load(payload)
         | 
| 54 | 
            +
                        else
         | 
| 55 | 
            +
                          YAML.load(payload)
         | 
| 56 | 
            +
                        end
         | 
| 55 57 | 
             
                      end
         | 
| 56 58 | 
             
                    end
         | 
| 57 59 | 
             
                end
         | 
| @@ -40,7 +40,7 @@ module ActiveRecord | |
| 40 40 | 
             
                # but the Book model connects to a separate database called "library_db"
         | 
| 41 41 | 
             
                # (this can even be a database on a different machine).
         | 
| 42 42 | 
             
                #
         | 
| 43 | 
            -
                # Book, ScaryBook and GoodBook will all use the same connection pool to
         | 
| 43 | 
            +
                # Book, ScaryBook, and GoodBook will all use the same connection pool to
         | 
| 44 44 | 
             
                # "library_db" while Author, BankAccount, and any other models you create
         | 
| 45 45 | 
             
                # will use the default connection pool to "my_application".
         | 
| 46 46 | 
             
                #
         | 
| @@ -202,6 +202,10 @@ module ActiveRecord | |
| 202 202 |  | 
| 203 203 | 
             
                    def index_options(table_name)
         | 
| 204 204 | 
             
                      index_options = as_options(index)
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                      # legacy reference index names are used on versions 6.0 and earlier
         | 
| 207 | 
            +
                      return index_options if options[:_uses_legacy_reference_index_name]
         | 
| 208 | 
            +
             | 
| 205 209 | 
             
                      index_options[:name] ||= polymorphic_index_name(table_name) if polymorphic
         | 
| 206 210 | 
             
                      index_options
         | 
| 207 211 | 
             
                    end
         | 
| @@ -1071,9 +1071,9 @@ module ActiveRecord | |
| 1071 1071 | 
             
                  # [<tt>:name</tt>]
         | 
| 1072 1072 | 
             
                  #   The constraint name. Defaults to <tt>fk_rails_<identifier></tt>.
         | 
| 1073 1073 | 
             
                  # [<tt>:on_delete</tt>]
         | 
| 1074 | 
            -
                  #   Action that happens <tt>ON DELETE</tt>. Valid values are +:nullify+, +:cascade | 
| 1074 | 
            +
                  #   Action that happens <tt>ON DELETE</tt>. Valid values are +:nullify+, +:cascade+, and +:restrict+
         | 
| 1075 1075 | 
             
                  # [<tt>:on_update</tt>]
         | 
| 1076 | 
            -
                  #   Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade | 
| 1076 | 
            +
                  #   Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade+, and +:restrict+
         | 
| 1077 1077 | 
             
                  # [<tt>:if_not_exists</tt>]
         | 
| 1078 1078 | 
             
                  #   Specifies if the foreign key already exists to not try to re-add it. This will avoid
         | 
| 1079 1079 | 
             
                  #   duplicate column errors.
         | 
| @@ -1125,7 +1125,7 @@ module ActiveRecord | |
| 1125 1125 | 
             
                  #   The name of the table that contains the referenced primary key.
         | 
| 1126 1126 | 
             
                  def remove_foreign_key(from_table, to_table = nil, **options)
         | 
| 1127 1127 | 
             
                    return unless supports_foreign_keys?
         | 
| 1128 | 
            -
                    return if options | 
| 1128 | 
            +
                    return if options.delete(:if_exists) == true && !foreign_key_exists?(from_table, to_table)
         | 
| 1129 1129 |  | 
| 1130 1130 | 
             
                    fk_name_to_delete = foreign_key_for!(from_table, to_table: to_table, **options).name
         | 
| 1131 1131 |  | 
| @@ -36,7 +36,7 @@ module ActiveRecord | |
| 36 36 | 
             
                  include Savepoints
         | 
| 37 37 |  | 
| 38 38 | 
             
                  SIMPLE_INT = /\A\d+\z/
         | 
| 39 | 
            -
                  COMMENT_REGEX = %r{(?:--.*\n) | 
| 39 | 
            +
                  COMMENT_REGEX = %r{(?:--.*\n)|/\*(?:[^*]|\*[^/])*\*/}m
         | 
| 40 40 |  | 
| 41 41 | 
             
                  attr_accessor :pool
         | 
| 42 42 | 
             
                  attr_reader :visitor, :owner, :logger, :lock
         | 
| @@ -224,14 +224,14 @@ module ActiveRecord | |
| 224 224 | 
             
                    @pool.connection_class
         | 
| 225 225 | 
             
                  end
         | 
| 226 226 |  | 
| 227 | 
            -
                  # The role ( | 
| 228 | 
            -
                  # non-multi role application,  | 
| 227 | 
            +
                  # The role (e.g. +:writing+) for the current connection. In a
         | 
| 228 | 
            +
                  # non-multi role application, +:writing+ is returned.
         | 
| 229 229 | 
             
                  def role
         | 
| 230 230 | 
             
                    @pool.role
         | 
| 231 231 | 
             
                  end
         | 
| 232 232 |  | 
| 233 | 
            -
                  # The shard ( | 
| 234 | 
            -
                  # a non-sharded application,  | 
| 233 | 
            +
                  # The shard (e.g. +:default+) for the current connection. In
         | 
| 234 | 
            +
                  # a non-sharded application, +:default+ is returned.
         | 
| 235 235 | 
             
                  def shard
         | 
| 236 236 | 
             
                    @pool.shard
         | 
| 237 237 | 
             
                  end
         | 
| @@ -711,6 +711,10 @@ module ActiveRecord | |
| 711 711 | 
             
                        options[:comment] = column.comment
         | 
| 712 712 | 
             
                      end
         | 
| 713 713 |  | 
| 714 | 
            +
                      unless options.key?(:auto_increment)
         | 
| 715 | 
            +
                        options[:auto_increment] = column.auto_increment?
         | 
| 716 | 
            +
                      end
         | 
| 717 | 
            +
             | 
| 714 718 | 
             
                      td = create_table_definition(table_name)
         | 
| 715 719 | 
             
                      cd = td.new_column_definition(column.name, type, **options)
         | 
| 716 720 | 
             
                      schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
         | 
| @@ -158,7 +158,21 @@ module ActiveRecord | |
| 158 158 | 
             
                        MySQL::TableDefinition.new(self, name, **options)
         | 
| 159 159 | 
             
                      end
         | 
| 160 160 |  | 
| 161 | 
            +
                      def default_type(table_name, field_name)
         | 
| 162 | 
            +
                        match = create_table_info(table_name).match(/`#{field_name}` (.+) DEFAULT ('|\d+|[A-z]+)/)
         | 
| 163 | 
            +
                        default_pre = match[2] if match
         | 
| 164 | 
            +
             | 
| 165 | 
            +
                        if default_pre == "'"
         | 
| 166 | 
            +
                          :string
         | 
| 167 | 
            +
                        elsif default_pre&.match?(/^\d+$/)
         | 
| 168 | 
            +
                          :integer
         | 
| 169 | 
            +
                        elsif default_pre&.match?(/^[A-z]+$/)
         | 
| 170 | 
            +
                          :function
         | 
| 171 | 
            +
                        end
         | 
| 172 | 
            +
                      end
         | 
| 173 | 
            +
             | 
| 161 174 | 
             
                      def new_column_from_field(table_name, field)
         | 
| 175 | 
            +
                        field_name = field.fetch(:Field)
         | 
| 162 176 | 
             
                        type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
         | 
| 163 177 | 
             
                        default, default_function = field[:Default], nil
         | 
| 164 178 |  | 
| @@ -168,9 +182,13 @@ module ActiveRecord | |
| 168 182 | 
             
                        elsif type_metadata.extra == "DEFAULT_GENERATED"
         | 
| 169 183 | 
             
                          default = +"(#{default})" unless default.start_with?("(")
         | 
| 170 184 | 
             
                          default, default_function = nil, default
         | 
| 171 | 
            -
                        elsif type_metadata.type == :text && default
         | 
| 185 | 
            +
                        elsif type_metadata.type == :text && default&.start_with?("'")
         | 
| 172 186 | 
             
                          # strip and unescape quotes
         | 
| 173 187 | 
             
                          default = default[1...-1].gsub("\\'", "'")
         | 
| 188 | 
            +
                        elsif default&.match?(/\A\d/)
         | 
| 189 | 
            +
                          # Its a number so we can skip the query to check if it is a function
         | 
| 190 | 
            +
                        elsif default && default_type(table_name, field_name) == :function
         | 
| 191 | 
            +
                          default, default_function = nil, default
         | 
| 174 192 | 
             
                        end
         | 
| 175 193 |  | 
| 176 194 | 
             
                        MySQL::Column.new(
         | 
| @@ -528,8 +528,10 @@ module ActiveRecord | |
| 528 528 | 
             
                        SELECT conname, pg_get_constraintdef(c.oid, true) AS constraintdef, c.convalidated AS valid
         | 
| 529 529 | 
             
                        FROM pg_constraint c
         | 
| 530 530 | 
             
                        JOIN pg_class t ON c.conrelid = t.oid
         | 
| 531 | 
            +
                        JOIN pg_namespace n ON n.oid = c.connamespace
         | 
| 531 532 | 
             
                        WHERE c.contype = 'c'
         | 
| 532 533 | 
             
                          AND t.relname = #{scope[:name]}
         | 
| 534 | 
            +
                          AND n.nspname = #{scope[:schema]}
         | 
| 533 535 | 
             
                      SQL
         | 
| 534 536 |  | 
| 535 537 | 
             
                      check_info.map do |row|
         | 
| @@ -104,7 +104,7 @@ module ActiveRecord | |
| 104 104 |  | 
| 105 105 | 
             
                  ##
         | 
| 106 106 | 
             
                  # :singleton-method:
         | 
| 107 | 
            -
                  # PostgreSQL supports multiple types for DateTimes. By default if you use  | 
| 107 | 
            +
                  # PostgreSQL supports multiple types for DateTimes. By default, if you use +datetime+
         | 
| 108 108 | 
             
                  # in migrations, Rails will translate this to a PostgreSQL "timestamp without time zone".
         | 
| 109 109 | 
             
                  # Change this in an initializer to use another NATIVE_DATABASE_TYPES. For example, to
         | 
| 110 110 | 
             
                  # store DateTimes as "timestamp with time zone":
         | 
| @@ -116,8 +116,8 @@ module ActiveRecord | |
| 116 116 | 
             
                  #   ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:my_custom_type] = { name: "my_custom_type_name" }
         | 
| 117 117 | 
             
                  #   ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type = :my_custom_type
         | 
| 118 118 | 
             
                  #
         | 
| 119 | 
            -
                  # If you're using  | 
| 120 | 
            -
                  # setting, you should immediately run bin/rails db:migrate to update the types in your schema.rb.
         | 
| 119 | 
            +
                  # If you're using +:ruby+ as your +config.active_record.schema_format+ and you change this
         | 
| 120 | 
            +
                  # setting, you should immediately run <tt>bin/rails db:migrate</tt> to update the types in your schema.rb.
         | 
| 121 121 | 
             
                  class_attribute :datetime_type, default: :timestamp
         | 
| 122 122 |  | 
| 123 123 | 
             
                  NATIVE_DATABASE_TYPES = {
         | 
| @@ -60,7 +60,7 @@ module ActiveRecord | |
| 60 60 | 
             
                    end
         | 
| 61 61 |  | 
| 62 62 | 
             
                    def remove_foreign_key(from_table, to_table = nil, **options)
         | 
| 63 | 
            -
                      return if options | 
| 63 | 
            +
                      return if options.delete(:if_exists) == true && !foreign_key_exists?(from_table, to_table)
         | 
| 64 64 |  | 
| 65 65 | 
             
                      to_table ||= options[:to_table]
         | 
| 66 66 | 
             
                      options = options.except(:name, :to_table, :validate)
         | 
| @@ -44,7 +44,7 @@ module ActiveRecord | |
| 44 44 | 
             
                #
         | 
| 45 45 | 
             
                #   ActiveRecord::Base.establish_connection(:production)
         | 
| 46 46 | 
             
                #
         | 
| 47 | 
            -
                # The exceptions AdapterNotSpecified, AdapterNotFound and +ArgumentError+
         | 
| 47 | 
            +
                # The exceptions AdapterNotSpecified, AdapterNotFound, and +ArgumentError+
         | 
| 48 48 | 
             
                # may be returned on an error.
         | 
| 49 49 | 
             
                def establish_connection(config_or_env = nil)
         | 
| 50 50 | 
             
                  config_or_env ||= DEFAULT_ENV.call.to_sym
         | 
| @@ -108,7 +108,7 @@ module ActiveRecord | |
| 108 108 | 
             
                  connections
         | 
| 109 109 | 
             
                end
         | 
| 110 110 |  | 
| 111 | 
            -
                # Connects to a role ( | 
| 111 | 
            +
                # Connects to a role (e.g. writing, reading, or a custom role) and/or
         | 
| 112 112 | 
             
                # shard for the duration of the block. At the end of the block the
         | 
| 113 113 | 
             
                # connection will be returned to the original role / shard.
         | 
| 114 114 | 
             
                #
         | 
    
        data/lib/active_record/core.rb
    CHANGED
    
    | @@ -60,7 +60,7 @@ module ActiveRecord | |
| 60 60 | 
             
                  ##
         | 
| 61 61 | 
             
                  # :singleton-method:
         | 
| 62 62 | 
             
                  # Force enumeration of all columns in SELECT statements.
         | 
| 63 | 
            -
                  # e.g.  | 
| 63 | 
            +
                  # e.g. <tt>SELECT first_name, last_name FROM ...</tt> instead of <tt>SELECT * FROM ...</tt>
         | 
| 64 64 | 
             
                  # This avoids +PreparedStatementCacheExpired+ errors when a column is added
         | 
| 65 65 | 
             
                  # to the database while the app is running.
         | 
| 66 66 | 
             
                  class_attribute :enumerate_columns_in_select_statements, instance_accessor: false, default: false
         | 
| @@ -238,7 +238,7 @@ module ActiveRecord | |
| 238 238 | 
             
                  def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
         | 
| 239 239 | 
             
                    case ActiveRecord.action_on_strict_loading_violation
         | 
| 240 240 | 
             
                    when :raise
         | 
| 241 | 
            -
                      message =  | 
| 241 | 
            +
                      message = reflection.strict_loading_violation_message(owner)
         | 
| 242 242 | 
             
                      raise ActiveRecord::StrictLoadingViolationError.new(message)
         | 
| 243 243 | 
             
                    when :log
         | 
| 244 244 | 
             
                      name = "strict_loading_violation.active_record"
         | 
| @@ -411,7 +411,7 @@ module ActiveRecord | |
| 411 411 | 
             
                    end
         | 
| 412 412 | 
             
                  end
         | 
| 413 413 |  | 
| 414 | 
            -
                  #  | 
| 414 | 
            +
                  # Override the default class equality method to provide support for decorated models.
         | 
| 415 415 | 
             
                  def ===(object) # :nodoc:
         | 
| 416 416 | 
             
                    object.is_a?(self)
         | 
| 417 417 | 
             
                  end
         | 
| @@ -2,7 +2,7 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            module ActiveRecord
         | 
| 4 4 | 
             
              module Encryption
         | 
| 5 | 
            -
                # Configuration API for  | 
| 5 | 
            +
                # Configuration API for ActiveRecord::Encryption
         | 
| 6 6 | 
             
                module Configurable
         | 
| 7 7 | 
             
                  extend ActiveSupport::Concern
         | 
| 8 8 |  | 
| @@ -52,9 +52,15 @@ module ActiveRecord | |
| 52 52 |  | 
| 53 53 | 
             
                    def install_auto_filtered_parameters_hook(application) # :nodoc:
         | 
| 54 54 | 
             
                      ActiveRecord::Encryption.on_encrypted_attribute_declared do |klass, encrypted_attribute_name|
         | 
| 55 | 
            -
                         | 
| 55 | 
            +
                        filter_parameter = [("#{klass.model_name.element}" if klass.name), encrypted_attribute_name.to_s].compact.join(".")
         | 
| 56 | 
            +
                        application.config.filter_parameters << filter_parameter unless excluded_from_filter_parameters?(filter_parameter)
         | 
| 56 57 | 
             
                      end
         | 
| 57 58 | 
             
                    end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    private
         | 
| 61 | 
            +
                      def excluded_from_filter_parameters?(filter_parameter)
         | 
| 62 | 
            +
                        ActiveRecord::Encryption.config.excluded_from_filter_parameters.find { |excluded_filter| excluded_filter.to_s == filter_parameter }
         | 
| 63 | 
            +
                      end
         | 
| 58 64 | 
             
                  end
         | 
| 59 65 | 
             
                end
         | 
| 60 66 | 
             
              end
         | 
| @@ -2,14 +2,14 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            module ActiveRecord
         | 
| 4 4 | 
             
              module Encryption
         | 
| 5 | 
            -
                #  | 
| 5 | 
            +
                # ActiveRecord::Encryption uses encryption contexts to configure the different entities used to
         | 
| 6 6 | 
             
                # encrypt/decrypt at a given moment in time.
         | 
| 7 7 | 
             
                #
         | 
| 8 | 
            -
                # By default, the library uses a default encryption context. This is the  | 
| 8 | 
            +
                # By default, the library uses a default encryption context. This is the Context that gets configured
         | 
| 9 9 | 
             
                # initially via +config.active_record.encryption+ options. Library users can define nested encryption contexts
         | 
| 10 10 | 
             
                # when running blocks of code.
         | 
| 11 11 | 
             
                #
         | 
| 12 | 
            -
                # See  | 
| 12 | 
            +
                # See Context.
         | 
| 13 13 | 
             
                module Contexts
         | 
| 14 14 | 
             
                  extend ActiveSupport::Concern
         | 
| 15 15 |  |