aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods
Commit message (Collapse)AuthorAgeFilesLines
* Use strings instead of symbols on calls to decorate_matching_attribute_typesDillon Welch2018-08-101-1/+1
| | | | | | The first thing this method does is run on the argument. This change passes in a string so we don't allocate a bunch of unnecessary extra strings by calling to_s on a symbol over and over.
* `becomes` should clear the mutation tracker which is created in ↵Ryuta Kamizono2018-05-111-1/+1
| | | | | | | | | | | | | | | | `after_initialize` `becomes` creates new object and copies attributes from the receiver. If new object has mutation tracker which is created in `after_initialize`, it should be cleared since it is for discarded attributes. But if the receiver doesn't have mutation tracker yet, it will not be cleared properly. It should be cleared regardless of whether the receiver has mutation tracker or not. Fixes #32867.
* Fix ActiveRecord::AttributeMethods::Dirty documentation [ci skip]Kieran Trezona-le Comte2018-05-071-20/+58
| | | | | | | | | | | | | | | Previously the documentation for the newly introduced (in 5.1) AR::Dirty methods was misleading, as it stated the the new methods were aliases for the old methods. This was false, and caused confusion when the differences in their implementation became apparent. This change attempts to describe the behaviour of these methods more accurately, also noting when they are likely to be useful (i.e. before or after saving a record). This change also makes minor updates to consistently format the documentation of this API, in accordance with the API Documentation Guidelines.
* Fix broken nodocsChris Arcand2018-04-131-1/+1
| | | | | This commit fixes all references in the codebase missing a trailing :, which causes the nodoc not to actually work :) [skip ci]
* Avoid generating full changes hash on every saveEugene Kenny2018-04-081-1/+1
| | | | | | | | | | `changed_attribute_names_to_save` is called in `keys_for_partial_write`, which is called on every save when partial writes are enabled. We can avoid generating the full changes hash by asking the mutation tracker for just the names of the changed attributes. At minimum this saves one array allocation per attribute, but will also avoid calling `Attribute#original_value` which is expensive for serialized attributes.
* Add AR::Base.base_class? predicateBogdan Gusiev2018-04-021-1/+1
|
* Revert "PERF: Recover `changes_applied` performance (#31698)"Sean Griffin2018-03-061-2/+4
| | | | This reverts commit a19e91f0fab13cca61acdb1f33e27be2323b9786.
* Ruby 2.4: take advantage of String#unpack1Jeremy Daer2018-03-012-2/+2
| | | | | https://bugs.ruby-lang.org/issues/12752 https://ruby-doc.org/core-2.4.0/String.html#method-i-unpack1
* Remove usage of strip_heredoc in the framework in favor of <<~Rafael Mendonça França2018-02-162-2/+2
| | | | | Some places we can't remove because Ruby still don't have a method equivalent to strip_heredoc to be called in an already existent string.
* PERF: Recover `changes_applied` performance (#31698)Ryuta Kamizono2018-01-221-4/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #30985 caused `object.save` performance regression since calling `changes` in `changes_applied` is very slow. We don't need to call the expensive method in `changes_applied` as long as `@attributes` is tracked by mutation tracker. https://gist.github.com/kamipo/1a9f4f3891803b914fc72ede98268aa2 Before: ``` Warming up -------------------------------------- create_string_columns 73.000 i/100ms Calculating ------------------------------------- create_string_columns 722.256 (± 5.8%) i/s - 3.650k in 5.073031s ``` After: ``` Warming up -------------------------------------- create_string_columns 96.000 i/100ms Calculating ------------------------------------- create_string_columns 950.224 (± 7.7%) i/s - 4.800k in 5.084837s ```
* Move Attribute and AttributeSet to ActiveModelLisa Ugray2017-11-091-94/+2
| | | | | Use these to back the attributes API. Stop automatically including ActiveModel::Dirty in ActiveModel::Attributes, and make it optional.
* [Active Record] require => require_relativeAkira Matsuda2017-10-211-1/+1
| | | | This basically reverts 9d4f79d3d394edb74fa2192e5d9ad7b09ce50c6d
* Merge pull request #30471 from dylanahsmith/remove-redundant-trackerAaron Patterson2017-09-271-23/+9
|\ | | | | activerecord: Remove a redundant mutation tracker
| * activerecord: Remove a redundant mutation trackerDylan Thacker-Smith2017-08-301-23/+9
| | | | | | | | | | | | | | The extra mutation tracker was needed in Rails 5.1 to preserve the old behaviour of `changes`, but now there is no difference between `changes` and `changes_to_save`, so `@mutation_tracker` can be removed.
* | PERF: Partially recover some performance when preloading.Guo Xiang Tan2017-09-263-6/+10
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Benchmark Script: ``` require 'active_record' require 'benchmark/ips' ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL')) ActiveRecord::Migration.verbose = false ActiveRecord::Schema.define do create_table :users, force: true do |t| t.string :name, :email t.integer :topic_id t.timestamps null: false end create_table :topics, force: true do |t| t.string :title t.timestamps null: false end end attributes = { name: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', email: 'foobar@email.com' } class Topic < ActiveRecord::Base has_many :users end class User < ActiveRecord::Base belongs_to :topic end 100.times do User.create!(attributes) end users = User.first(50) Topic.create!(title: 'This is a topic', users: users) Benchmark.ips do |x| x.config(time: 10, warmup: 5) x.report("preload") do User.includes(:topic).all.to_a end end ``` Before: ``` Calculating ------------------------------------- preload 40.000 i/100ms ------------------------------------------------- preload 407.962 (± 1.5%) i/s - 4.080k ``` After: ``` alculating ------------------------------------- preload 43.000 i/100ms ------------------------------------------------- preload 427.567 (± 1.6%) i/s - 4.300k ```
* Use tt in doc for ActiveRecord [ci skip]Yoshiyuki Hirano2017-08-271-11/+11
|
* Add :nodoc: for ActiveRecord::AttributeMethods [ci skip]Yoshiyuki Hirano2017-08-263-3/+3
|
* Don't expose `write_attribute_without_type_cast`Ryuta Kamizono2017-08-161-6/+5
| | | | | | `write_attribute_without_type_cast` is defined as a private method in `AttributeMethods::Write`, but `AttributeMethods::Dirty` overrode it as a public method. It should be kept the original visibility.
* Allow `serialize` with a custom coder on `json` and `array` columnsRyuta Kamizono2017-08-131-7/+4
| | | | | | | We already have a test case for `serialize` with a custom coder in `PostgresqlHstoreTest`. https://github.com/rails/rails/blob/v5.1.3/activerecord/test/cases/adapters/postgresql/hstore_test.rb#L316-L335
* Document `ActiveRecord::AttributeMethods::Dirty`Sean Griffin2017-08-081-9/+9
| | | | | This module has behavior that is not present in `ActiveModel::Dirty`, which is intended to be public API.
* Merge pull request #29520 from kirs/serialize-vs-postgres-native-columnSean Griffin2017-08-041-0/+24
|\ | | | | Do not let use `serialize` on native JSON/array column
| * Do not let use `serialize` on native JSON/array columnKir Shatrov2017-08-041-0/+24
| |
* | Merge pull request #29724 from eugeneius/sync_primary_keyMatthew Draper2017-08-022-0/+6
|\ \ | |/ |/| Sync transaction state when accessing primary key
| * Sync transaction state when accessing primary keyEugene Kenny2017-07-092-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If a record is modified inside a transaction, it must check the outcome of that transaction before accessing any state which would no longer be valid if it was rolled back. For example, consider a new record that was saved inside a transaction which was later rolled back: it should be restored to its previous state so that saving it again inserts a new row into the database instead of trying to update a row that no longer exists. The `id` and `id=` methods defined on the PrimaryKey module implement this correctly, but when a model uses a custom primary key, the reader and writer methods for that attribute must check the transaction state too. The `read_attribute` and `write_attribute` methods also need to check the transaction state when accessing the primary key.
* | Use frozen-string-literal in ActiveRecordKir Shatrov2017-07-197-0/+14
| |
* | Remove deprecated code concerning non-attributes and `*_will_change!`Sean Griffin2017-07-181-11/+1
| |
* | Remove deprecated code concerning dirty methods in after callbacksSean Griffin2017-07-181-79/+8
| |
* | [Action Record] `rubocop -a --only Layout/EmptyLineAfterMagicComment`Koichi ITO2017-07-111-0/+1
|/
* Merge pull request #29495 from eugeneius/_write_attributeMatthew Draper2017-07-093-9/+15
|\ | | | | Improve the performance of writing attributes
| * Rename raw_write_attribute to write_attribute_without_type_castEugene Kenny2017-07-072-7/+7
| | | | | | | | | | | | | | | | This name more accurately describes what the method does, and also disambiguates it from `_write_attribute`, which ignores aliases. We can also make the method private, since it's not public API and only called from one place - `update_columns` - without an explicit receiver.
| * Improve the performance of writing attributesEugene Kenny2017-06-182-5/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Using a similar approach to 08576b94ad4f19dfc368619d7751e211d23dcad8, this change adds a new internal `_write_attribute` method which bypasses the code that checks for attribute aliases and custom primary keys. We can use this method instead of `write_attribute` when we know that we have the name of the actual column to be updated and not an alias. This makes writing an attribute with `attribute=` about 18% faster. Benchmark: ``` begin require "bundler/inline" rescue LoadError => e $stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler" raise e end gemfile(true) do source "https://rubygems.org" gem "rails", github: "rails/rails" gem "arel", github: "rails/arel" gem "sqlite3" gem "benchmark-ips" end require "active_record" ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:") ActiveRecord::Schema.define do create_table :posts, force: true do |t| end end class Post < ActiveRecord::Base end post = Post.new(id: 1) Benchmark.ips do |x| x.report("attribute=") { post.id = post.id + 1 } end ``` Before: Warming up -------------------------------------- attribute= 25.889k i/100ms Calculating ------------------------------------- attribute= 290.946k (± 3.1%) i/s - 1.476M in 5.077036s After: Warming up -------------------------------------- attribute= 30.056k i/100ms Calculating ------------------------------------- attribute= 345.088k (± 4.8%) i/s - 1.743M in 5.064264s
* | [Active Record] require => require_relativeAkira Matsuda2017-07-011-1/+1
|/
* Don't map id to primary key in raw_write_attributeEugene Kenny2017-06-151-15/+6
| | | | | | | | | | | | | | The `raw_write_attribute` method is used to update a record's attributes to reflect the new state of the database in `update_columns`. The hash provided to `update_columns` is turned into an UPDATE query directly, which means passing an `id` key results in an update to the `id` column, even if the model uses a different attribute as its primary key. When updating the record, we don't want to apply the `id` column change to the primary key attribute, since that's not what happened in the query. Without the code to handle this case, `write_attribute_with_type_cast` no longer contains any logic shared between `raw_write_attribute` and `write_attribute`, so we can inline the code into those two methods.
* Prevent extra `sync_with_transaction_state`Ryuta Kamizono2017-06-151-5/+2
| | | | | `sync_with_transaction_state` in `to_key` is unneeded because `id` also does.
* Avoid overwriting the methods of `AttributeMethods::PrimaryKey`Ryuta Kamizono2017-06-071-7/+3
| | | | | | | | | Currently the methods of `AttributeMethods::PrimaryKey` are overwritten by `define_attribute_methods`. It will be broken if a table that customized primary key has non primary key id column. It should not be overwritten if a table has any primary key. Fixes #29350.
* Use mattr_accessor default: option throughout the projectGenadi Samokovarov2017-06-031-2/+1
|
* Add option for class_attribute default (#29270)David Heinemeier Hansson2017-05-292-7/+3
| | | | | | | | | | | | * Allow a default value to be declared for class_attribute * Convert to using class_attribute default rather than explicit setter * Removed instance_accessor option by mistake * False is a valid default value * Documentation
* Move around AR::Dirty and fix _attribute methodAaron Patterson2017-04-141-4/+0
| | | | | | We already have a _read_attribute method that can get the value we need from the model. Lets define that method in AM::Dirty and use the existing one from AR::Dirty rather than introducing a new method.
* Fix inconsistency with changed attributes when overriding AR attribute readerbogdanvlviv2017-04-121-0/+4
|
* Add missing backtick to deprecation messageyuuji.yaginuma2017-03-311-1/+1
|
* Soft-deprecate the top-level HashWithIndifferentAccess classRobin Dupret2017-02-251-3/+3
| | | | | | | Since using a `ActiveSupport::Deprecation::DeprecatedConstantProxy` would prevent people from inheriting this class and extending it from the `ActiveSupport::HashWithIndifferentAccess` one would break the ancestors chain, that's the best option we have here.
* Revert "Merge pull request #27925 from robin850/hwia-removal"Kasper Timm Hansen2017-02-201-3/+3
| | | | | | | | | Pointed out by @matthewd that the HWIA subclass changes the AS scoped class and top-level HWIA hierarchies out from under existing classes. This reverts commit 71da39097b67114329be6d8db7fe6911124531af, reversing changes made to 41c33bd4b2ec3f4a482e6030b6fda15091d81e4a.
* Deprecate the top-level `HashWithIndifferentAccess` contantRobin Dupret2017-02-191-3/+3
| | | | | | | | | This constant was kept for the sake of backward compatibility; it is still available under `ActiveSupport::HashWithIndifferentAccess`. Furthermore, since Ruby 2.5 (https://bugs.ruby-lang.org/issues/11547) won't support top level constant lookup, people would have to update their code anyway.
* Remove unused requireRyuta Kamizono2017-02-121-2/+0
| | | | | | These files are not using `strip_heredoc`. Closes #27976
* Deprecate calling `attr_will_change!` with non-attributesSean Griffin2017-02-111-1/+11
| | | | | | | | | | | | | This was never really intended to work (at least not without calling `define_attribute_methods`, which is less common with Active Record). As we move forward the intention is to require the use of `attribute` over `attr_accessor` for more complex model behavior both on Active Record and Active Model, so this behavior is deprecated. Fixes #27956. Close #27963. [Alex Serban & Sean Griffin]
* Fix inspection behavior when the :id column is not primary keynamusyaka2017-02-091-1/+1
|
* Report the attribute on ActiveRecord::SerializationTypeMismatchKir Shatrov2017-01-291-1/+1
|
* `self.` is not needed when calling its own instance methodAkira Matsuda2017-01-051-1/+1
| | | | Actually, private methods cannot be called with `self.`, so it's not just redundant, it's a bad habit in Ruby
* Merge pull request #27491 from kamipo/add_missing_emit_warningSean Griffin2017-01-031-0/+5
|\ | | | | Add missing `emit_warning_if_needed` for `changed?`
| * Add missing `emit_warning_if_needed` for `changed?`Ryuta Kamizono2016-12-291-0/+5
| |