aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods/dirty.rb
Commit message (Collapse)AuthorAgeFilesLines
* Attribute assignment and type casting has nothing to do with columnsSean Griffin2015-01-311-3/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It's finally finished!!!!!!! The reason the Attributes API was kept private in 4.2 was due to some publicly visible implementation details. It was previously implemented by overloading `columns` and `columns_hash`, to make them return column objects which were modified with the attribute information. This meant that those methods LIED! We didn't change the database schema. We changed the attribute information on the class. That is wrong! It should be the other way around, where schema loading just calls the attributes API for you. And now it does! Yes, this means that there is nothing that happens in automatic schema loading that you couldn't manually do yourself. (There's still some funky cases where we hit the connection adapter that I need to handle, before we can turn off automatic schema detection entirely.) There were a few weird test failures caused by this that had to be fixed. The main source came from the fact that the attribute methods are now defined in terms of `attribute_names`, which has a clause like `return [] unless table_exists?`. I don't *think* this is an issue, since the only place this caused failures were in a fake adapter which didn't override `table_exists?`. Additionally, there were a few cases where tests were failing because a migration was run, but the model was not reloaded. I'm not sure why these started failing from this change, I might need to clear an additional cache in `reload_schema_from_cache`. Again, since this is not normal usage, and it's expected that `reset_column_information` will be called after the table is modified, I don't think it's a problem. Still, test failures that were unrelated to the change are worrying, and I need to dig into them further. Finally, I spent a lot of time debugging issues with the mutex used in `define_attribute_methods`. I think we can just remove that method entirely, and define the attribute methods *manually* in the call to `define_attribute`, which would simplify the code *tremendously*. Ok. now to make this damn thing public, and work on moving it up to Active Model.
* Errors raised in `type_cast_for_database` no longer raise on assignmentSean Griffin2015-01-231-1/+1
| | | | Fixes #18580.
* Don't calculate in-place changes on attribute assignmentSean Griffin2015-01-181-1/+1
| | | | | | | | | | | When an attribute is assigned, we determine if it was already marked as changed so we can determine if we need to clear the changes, or mark it as changed. Since this only affects the `attributes_changed_by_setter` hash, in-place changes are irrelevant to this process. Since calculating in-place changes can be expensive, we can just skip it here. I also added a test for the only edge case I could think of that would be affected by this change.
* Don't attempt to save dirty attributes which are not persistableSean Griffin2015-01-101-1/+1
| | | | | | | | | | | | | | | | This sets a precident for how we handle `attribute` calls, which aren't backed by a database column. We should not take this as a conscious decision on how to handle them, and this can change when we make `attribute` public if we have better ideas in the future. As the composed attributes API gets fleshed out, I expect the `persistable_attributes` method to change to `@attributes.select(&:persistable).keys`, or some more performant variant there-of. This can probably go away completely once we fully move dirty checking into the attribute objects once it gets moved up to Active Model. Fixes #18407
* Don't calculate all in-place changes to determine if attribute_changed?Sean Griffin2014-12-221-0/+4
| | | | | | | | | Calling `changed_attributes` will ultimately check if every mutable attribute has changed in place. Since this gets called whenever an attribute is assigned, it's extremely slow. Instead, we can avoid this calculation until we actually need it. Fixes #18029
* Ensure numericality validations work with mutationSean Griffin2014-12-011-6/+6
| | | | | | | | | | | | | | | | | | | | | The detection of in-place changes caused a weird unexpected issue with numericality validations. That validator (out of necessity) works on the `_before_type_cast` version of the attribute, since on an `:integer` type column, a non-numeric string would type cast to 0. However, strings are mutable, and we changed strings to ensure that the post type cast version of the attribute was a different instance than the before type cast version (so the mutation detection can work properly). Even though strings are the only mutable type for which a numericality validation makes sense, special casing strings would feel like a strange change to make here. Instead, we can make the assumption that for all mutable types, we should work on the post-type-cast version of the attribute, since all cases which would return 0 for non-numeric strings are immutable. Fixes #17852
* Improve the performance of reading attributesSean Griffin2014-11-181-1/+1
| | | | | | | We added a comparison to "id", and call to `self.class.primary_key` a *lot*. We also have performance hits from `&block` all over the place. We skip the check in a new method, in order to avoid breaking the behavior of `read_attribute`
* Cache the value of `changed_attributes` when calling `changes_applied`Sean Griffin2014-08-221-1/+20
| | | | | | | `changes_applied` calles `changes`, which will call `changed_attributes` multiple times in a loop. This method actually performs work now, so we should cache the results while looping over it when we know it cannot change.
* Don't calculate in-place changes twiceSean Griffin2014-08-221-8/+0
| | | | | | Now that `changed_attributes` includes in place changes, we don't need to override these methods in Active Record. Partially fixes the performance regression caused by #16189
* Implement `_was` and `changes` for in-place mutations of AR attributesSean Griffin2014-08-161-11/+14
|
* Deprecate ActiveModel::Dirty#reset_changes in favor of ↵Rafael Mendonça França2014-07-151-2/+2
| | | | | | | | | #clear_changes_information This method name is causing confusion with the `reset_#{attribute}` methods. While `reset_name` set the value of the name attribute for the previous value the `reset_changes` only discard the changes and previous changes.
* Return a null object from `AttributeSet#[]`Sean Griffin2014-06-201-3/+3
|
* Use `column_defaults` in dirty for checking changed defaultsSean Griffin2014-06-171-11/+3
| | | | | | We no longer need to "init changed attributes" from the initializer, either, as there is no longer a case where a given value would differ from the default, but would not already be marked as changed.
* Refactor in-place dirty checking to use the attribute objectSean Griffin2014-06-161-9/+3
|
* Detect in-place changes on mutable AR attributesSean Griffin2014-06-131-6/+77
| | | | | | We have several mutable types on Active Record now. (Serialized, JSON, HStore). We need to be able to detect if these have been modified in place.
* Do not type cast twice on attribute assignmentSean Griffin2014-06-071-11/+20
| | | | | | | | | | | | | The definition of `write_attribute` in dirty checking ultimately leads to the columns calling `type_cast` on the value to perform the comparison. However, this is a potentially expensive computation that we cache when it occurs in `read_attribute`. The only case that we need the non-type-cast form is for numeric, so we pass that through as well (something I'm looking to remove in the future). This also reduces the number of places that manually access various stages in an attribute's type casting lifecycle, which will aid in one of the larger refactorings that I'm working on.
* Return a null column when no column exists for an attributeSean Griffin2014-06-031-2/+1
|
* Refactor determination of whether the field has changedSean Griffin2014-06-031-27/+2
| | | | | The types know more about what is going on than the dirty module. Let's ask them!
* Rename attribute related instance variables to better express intentSean Griffin2014-05-301-1/+1
| | | | | | | | | `@attributes` was actually used for `_before_type_cast` and friends, while `@attributes_cache` is the type cast version (and caching is the wrong word there, but I'm working on removing the conditionals around that). I opted for `@raw_attributes`, because `_before_type_cast` is also semantically misleading. The values in said hash are in the state given by the form builder or database, so raw seemed to be a good word.
* [Active Record] Renamed private methods create_record and update_recordPrathamesh Sonpatki2014-02-201-2/+2
| | | | | | This is to ensure that they are not accidentally called by the app code. They are renamed to _create_record and _update_record respectively. Closes #11645
* Merge pull request #13799 from kbrock/better_dirtyJeremy Kemper2014-01-221-1/+21
|\ | | | | Better ActiveRecord hierarchy for Dirty and others
| * Move changed_attributes into dirty.rbKeenan Brock2014-01-221-1/+21
| | | | | | Move serialization dirty into serialization.rb
* | Add more tests for the dirty feature for enumsRafael Mendonça França2014-01-211-1/+0
| |
* | Extract all attribute changed work to its own methodRafael Mendonça França2014-01-211-3/+7
|/ | | | This will make easier to hook on this feature to customize the behavior
* Merge pull request #10816 from bogdan/less-dirty-dirtyRafael Mendonça França2013-09-231-9/+6
| | | | Make AM::Dirty less dirty to plugin into AR or other library
* Removed deprecated methods partial_updates and familyNeeraj Singh2013-07-021-11/+0
| | | | | Removed deprecated methods `partial_updates`, `partial_updates?` and `partial_updates=`
* assigning '0.0' to a nullable numeric column does not make it dirtyYves Senn2013-03-051-1/+5
|
* These are already required through AS/railsAkira Matsuda2013-01-071-1/+0
| | | | | | * dependencies/autoload * concern * deprecation
* Rename update_attributes method to update, keep update_attributes as an aliasAmparo Luna + Guillermo Iguaran2013-01-031-2/+2
|
* Remove ActiveRecord::ModelJon Leighton2012-10-261-6/+2
| | | | | | | | | | In the end I think the pain of implementing this seamlessly was not worth the gain provided. The intention was that it would allow plain ruby objects that might not live in your main application to be subclassed and have persistence mixed in. But I've decided that the benefit of doing that is not worth the amount of complexity that the implementation introduced.
* Revert "Get rid of the ActiveRecord::Model::DeprecationProxy thing."Jeremy Kemper2012-10-201-1/+1
| | | | This reverts commit 83846838252397b3781eed165ca301e05db39293.
* Get rid of the ActiveRecord::Model::DeprecationProxy thing.Jon Leighton2012-10-191-1/+1
| | | | | | | | | | | | | | | | | I think it's going to be too much pain to try to transition the :active_record load hook from executing against Base to executing against Model. For example, after Model is included in Base, and modules included in Model will no longer get added to the ancestors of Base. So plugins which wish to be compatible with both Model and Base should use the :active_record_model load hook which executes *before* Base gets loaded. In general, ActiveRecord::Model is an advanced feature at the moment and probably most people will continue to inherit from ActiveRecord::Base for the time being.
* Rename the partial_updates config to partial_writesJon Leighton2012-10-191-6/+18
| | | | This reflects the fact that it now impact inserts as well as updates.
* The default value of a text/blob in mysql strict mode should be nilJon Leighton2012-10-191-11/+1
| | | | | | | | | In non-strict mode it is '', but if someone is in strict mode then we should honour the strict semantics. Also, this removes the need for a completely horrible hack in dirty.rb. Closes #7780
* Merge branch 'master' of github.com:lifo/docrailsVijay Dev2012-09-281-4/+4
|\ | | | | | | | | Conflicts: actionpack/lib/action_view/helpers/asset_tag_helper.rb
| * fix AR::AttributeMethods::Dirty :nodoc: [ci skip]Francesco Rodriguez2012-09-211-4/+4
| |
* | Support for partial inserts.Jon Leighton2012-09-281-3/+17
|/ | | | | | | | | | | When inserting new records, only the fields which have been changed from the defaults will actually be included in the INSERT statement. The other fields will be populated by the database. This is more efficient, and also means that it will be safe to remove database columns without getting subsequent errors in running app processes (so long as the code in those processes doesn't contain any references to the removed column).
* load active_support/core_ext/class/attribute in active_support/railsXavier Noria2012-08-021-1/+0
|
* load active_support/core_ext/object/blank in active_support/railsXavier Noria2012-08-021-1/+0
|
* Do not consider the numeric attribute as changed if the old value isRafael Mendonça França2012-08-021-1/+1
| | | | | | | | | | | | | | | | | | | | | | | zero and the new value is not a string. Before this commit this was the behavior r = Review.find_by_issue(0) r.issue => 0 r.changes => {} r.issue = 0 => 0 r.changed? => true r.changes => {"issue"=>[0,0]} Fixes #7237 Conflicts: activerecord/CHANGELOG.md
* changed the firm of changes_from_zero_to_string?Angelo capilleri2012-06-211-2/+2
| | | | delete *column* because is unused by the method.
* Refactor the conditionalsRafael Mendonça França2012-06-191-7/+7
|
* Validates_numericality_of is skipped when changing 0 to to non-empty stringAngelo capilleri2012-06-191-5/+15
| | | | | | | | | | This happens when A has_many many B and A accepts_nested_attributes B that has a numeric colum with initial 0 value. So a.update_attributes({:b_attributes => { :id => b.id, :numeric => 'foo' }}) passes the validation test but, the value of :numeric doesn't change. his commit forces that the update fails with the above conditions. Fixes #6393 Fixes #2331
* Simplify AR configuration code.Jon Leighton2012-06-151-2/+7
| | | | | Get rid of ActiveModel::Configuration, make better use of ActiveSupport::Concern + class_attribute, etc.
* Remove IdentityMapCarlos Antonio da Silva2012-03-131-5/+0
|
* remove unnecessary codeSergey Nartimov2012-02-281-6/+0
| | | | | it was added in 36129f21b86db4bd69e932e586129e246c2a5ca8 but isn't useful anymore as corresponding tests pass without it
* Rename field_changed? to _field_changed? so that users can create a field ↵Akira Matsuda2012-02-141-3/+3
| | | | named field
* Support configuration on ActiveRecord::Model.Jon Leighton2011-12-281-1/+1
| | | | | | | | | | | | | | | The problem: We need to be able to specify configuration in a way that can be inherited to models that include ActiveRecord::Model. So it is no longer sufficient to put 'top level' config on ActiveRecord::Base, but we do want configuration specified on ActiveRecord::Base and descendants to continue to work. So we need something like class_attribute that can be defined on a module but that is inherited when ActiveRecord::Model is included. The solution: added ActiveModel::Configuration module which provides a config_attribute macro. It's a bit specific hence I am not putting this in Active Support or making it a 'public API' at present.
* fix indentJon Leighton2011-11-301-3/+3
|
* Merge remote branch 'rails/master' into identity_mapEmilio Tagua2010-12-201-1/+2
|\ | | | | | | | | | | | | | | Conflicts: activerecord/lib/active_record/associations/association_proxy.rb activerecord/lib/active_record/autosave_association.rb activerecord/lib/active_record/base.rb activerecord/lib/active_record/persistence.rb