aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/dirty_test.rb
Commit message (Collapse)AuthorAgeFilesLines
* Deprecate calling `attr_will_change!` with non-attributesSean Griffin2017-02-111-0/+8
| | | | | | | | | | | | | 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]
* Deprecate the behavior of AR::Dirty inside of after_(create|update|save) ↵Sean Griffin2016-11-011-0/+83
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | callbacks We pretty frequently get bug reports that "dirty is broken inside of after callbacks". Intuitively they are correct. You'd expect `Model.after_save { puts changed? }; model.save` to do the same thing as `model.save; puts model.changed?`, but it does not. However, changing this goes much farther than just making the behavior more intuitive. There are a _ton_ of places inside of AR that can be drastically simplified with this change. Specifically, autosave associations, timestamps, touch, counter cache, and just about anything else in AR that works with callbacks have code to try to avoid "double save" bugs which we will be able to flat out remove with this change. We introduce two new sets of methods, both with names that are meant to be more explicit than dirty. The first set maintains the old behavior, and their names are meant to center that they are about changes that occurred during the save that just happened. They are equivalent to `previous_changes` when called outside of after callbacks, or once the deprecation cycle moves. The second set is the new behavior. Their names imply that they are talking about changes from the database representation. The fact that this is what we really care about became clear when looking at `BelongsTo.touch_record` when tests were failing. I'm unsure that this set of methods should be in the public API. Outside of after callbacks, they are equivalent to the existing methods on dirty. Dirty itself is not deprecated, nor are the methods inside of it. They will only emit the warning when called inside of after callbacks. The scope of this breakage is pretty large, but the migration path is simple. Given how much this can improve our codebase, and considering that it makes our API more intuitive, I think it's worth doing.
* Added ability update locking_column valuebogdanvlviv2016-10-211-1/+1
|
* improve error message when include assertions failMichael Grosser2016-09-161-3/+3
| | | | | | assert [1, 3].includes?(2) fails with unhelpful "Asserting failed" message assert_includes [1, 3], 2 fails with "Expected [1, 3] to include 2" which makes it easier to debug and more obvious what went wrong
* Add three new rubocop rulesRafael Mendonça França2016-08-161-5/+5
| | | | | | | | Style/SpaceBeforeBlockBraces Style/SpaceInsideBlockBraces Style/SpaceInsideHashLiteralBraces Fix all violations in the repository.
* Add `Style/EmptyLines` in `.rubocop.yml` and remove extra empty linesRyuta Kamizono2016-08-071-2/+0
|
* modernizes hash syntax in activerecordXavier Noria2016-08-061-21/+21
|
* applies new string literal convention in activerecord/testXavier Noria2016-08-061-96/+96
| | | | | The current code base is not uniform. After some discussion, we have chosen to go with double quotes by default.
* systematic revision of =~ usage in ARXavier Noria2016-07-231-1/+1
| | | | | Where appropriatei, prefer the more concise Regexp#match?, String#include?, String#start_with?, or String#end_with?
* Remove dead code from testsSean Griffin2016-06-091-17/+0
| | | | | This code was added in 81286f858770e0b95e15af37f19156b044ec6a95, but was not used by that commit and does not appear to have ever been used.
* Ensure that records with unselected fields can be updatedSean Griffin2016-06-021-0/+11
| | | | | | | | | | | | | | As part of refactoring mutation detection to be more performant, we introduced the concept of `original_value` to `Attribute`. This was not overridden in `Attribute::Uninitialized` however, so assigning ot an uninitialized value and calling `.changed?` would raise `NotImplementedError`. We are using a sentinel value rather than checking the result of `original_attribute.initialized?` in `changed?` because `original_value` might go through more than one node in the tree. Fixes #25228
* prevent 'attribute_changed?' from returning nilSen-Zhang2016-04-111-2/+2
|
* Don't assert fractional seconds can be applied on unsupported adaptersSean Griffin2015-09-241-0/+1
| | | | | | | This was passing prior to 20b177b78ef5d21c8cc255f0376f6b2e948de234, because we were not properly applying our contract that `model.attr == model.tap(&:save).reload.attr` for this case. Now that that has been resolved, this test is invalid on some adapters
* Remove debug statementsSean Griffin2015-09-241-4/+1
| | | | They didn't help.
* Add a few debug statements to figure out the build failureSean Griffin2015-09-241-0/+3
| | | | Nobody can replicate locally and the failure makes no sense
* Don't rely on subsecond precision being applied in testsSean Griffin2015-09-231-2/+16
| | | | | | When I originally reviewed the #20317, I believe these changes were present, but it appears that it was later updated so that they were removed. Since Travis hadn't re-run the build, this slipped through.
* Don't crash when mutating attributes in a getterSean Griffin2015-06-121-0/+16
| | | | | | | | | | | If a getter has side effects on the DB, `changes_applied` will be called twice. The second time will try and remove the changed attributes cache, and will crash because it's already been unset. This also demonstrates that we shouldn't assume that calling getters won't change the value of `changed_attributes`, and we need to clear the cache if an attribute is modified. Fixes #20531.
* Persist user provided default values, even if unchangedSean Griffin2015-05-281-26/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a usability change to fix a quirk from our definition of partial writes. By default, we only persist changed attributes. When creating a new record, this is assumed that the default values came from the database. However, if the user provided a default, it will not be persisted, since we didn't see it as "changed". Since this is a very specific case, I wanted to isolate it with the other quirks that come from user provided default values. The number of edge cases which are presenting themselves are starting to make me wonder if we should just remove the ability to assign a default, in favor of overriding `initialize`. For the time being, this is required for the attributes API to not have confusing behavior. We had to delete one test, since this actually changes the meaning of `.changed?` on Active Record models. It now specifically means `changed_from_database?`. While I think this will make the attributes API more ergonomic to use, it is a subtle change in definition (though not a backwards incompatible one). We should probably figure out the right place to document this. (Feel free to open a PR doing that if you're reading this). /cc @rafaelfranca @kirs @senny This is an alternate implementation of #19921. Close #19921. [Sean Griffin & Kir Shatrov]
* Rm `Type#type_cast`Sean Griffin2015-02-171-1/+1
| | | | | | | | | This helper no longer makes sense as a separate method. Instead I'll just have `deserialize` call `cast` by default. This led to a random infinite loop in the `JSON` pg type, when it called `super` from `deserialize`. Not really a great way to fix that other than not calling super, or continuing to have the separate method, which makes the public API differ from what we say it is.
* `type_cast_for_database` -> `serialize`Sean Griffin2015-02-171-2/+2
|
* Allow a symbol to be passed to `attribute`, in place of a type objectSean Griffin2015-02-061-1/+1
| | | | | | | | | | | | | | | | | | The same is not true of `define_attribute`, which is meant to be the low level no-magic API that sits underneath. The differences between the two APIs are: - `attribute` - Lazy (the attribute will be defined after the schema has loaded) - Allows either a type object or a symbol - `define_attribute` - Runs immediately (might get trampled by schema loading) - Requires a type object This was the last blocker in terms of public interface requirements originally discussed for this feature back in May. All the implementation blockers have been cleared, so this feature is probably ready for release (pending one more look-over by me).
* Don't calculate in-place changes on attribute assignmentSean Griffin2015-01-181-0/+8
| | | | | | | | | | | 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-0/+13
| | | | | | | | | | | | | | | | 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
* Remove deprecated `ActiveModel::Dirty#reset_#{attribute}` and ↵Rafael Mendonça França2015-01-041-12/+0
| | | | `ActiveModel::Dirty#reset_changes`.
* PostgreSQL, Fix change detection caused by wrong data for bytea unescaping.Lars Kanis2014-12-291-1/+8
| | | | | | | | | | This showed up when running BinaryTest#test_load_save with the more restrictive input string handling of pg-0.18.0.pre20141117110243.gem . Bytea values sent to the server are in binary format, but are returned back as escaped text. To fulfill the assumption that type_cast_from_database(type_cast_for_database(binary)) == binary we unescape only, if the value was really received from the server.
* Don't calculate all in-place changes to determine if attribute_changed?Sean Griffin2014-12-221-0/+15
| | | | | | | | | 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
* User Model#last to certainly get lastly created dataAkira Matsuda2014-08-281-1/+1
| | | | This test would fail when executed after any test that calls fixtures(:binaries)
* Correctly detect mutation on serialized columns mapping to binarySean Griffin2014-08-271-0/+16
| | | | Fixes #16701
* Implement `_was` and `changes` for in-place mutations of AR attributesSean Griffin2014-08-161-0/+21
|
* Deprecate `reset_#{attribute}` in favor of `restore_#{attribute}`.Rafael Mendonça França2014-07-151-2/+14
| | | | | | | | | These methods may cause confusion with the `reset_changes` that behaves differently of them. Also rename undo_changes to restore_changes to match this new set of methods.
* Detect in-place modifications on StringsSean Griffin2014-06-171-5/+3
|
* Detect in-place changes on mutable AR attributesSean Griffin2014-06-131-1/+10
| | | | | | 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.
* Make `_before_type_cast` actually be before type castSean Griffin2014-06-091-4/+2
| | | | | | | | | | | | | - The following is now true for all types, all the time - `model.attribute_before_type_cast == given_value` - `model.attribute == model.save_and_reload.attribute` - `model.attribute == model.dup.attribute` - `model.attribute == YAML.load(YAML.dump(model)).attribute` - Removes the remaining types implementing `type_cast_for_write` - Simplifies the implementation of time zone aware attributes - Brings tz aware attributes closer to being implemented as an attribute decorator - Adds additional point of control for custom types
* Rename `property` to `attribute`Sean Griffin2014-06-071-1/+1
| | | | For consistency with https://github.com/rails/rails/pull/15557
* Keep column defaults in type cast formSean Griffin2014-06-031-0/+28
| | | | | | | | | | The contract of `_field_changed?` assumes that the old value is always type cast. That is not the case for the value in `Column#default` as things are today. It appears there are other public methods that assume that `Column#default` is type cast, as well. The reason for this change originally was because the value gets put into `@raw_attributes` in initialize. This reverts to the old behavior on `Column`, and updates `initialize` to make sure that the values are in the right format.
* Add integration test for #12459George Guimarães2013-12-051-0/+8
|
* prevent `time_zone_aware_attributes` test leak. follow-up to #12633.Yves Senn2013-10-251-21/+21
|
* Removed deprecated methods partial_updates and familyNeeraj Singh2013-07-021-14/+0
| | | | | Removed deprecated methods `partial_updates`, `partial_updates?` and `partial_updates=`
* also assign nil in dirty nullable_datetime test. #10237Yves Senn2013-04-221-3/+5
|
* assigning '0.0' to a nullable numeric column does not make it dirtyYves Senn2013-03-051-0/+15
|
* Fix handling of dirty time zone aware attributesLilibeth De La Cruz2013-01-261-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | Previously, when `time_zone_aware_attributes` were enabled, after changing a datetime or timestamp attribute and then changing it back to the original value, `changed_attributes` still tracked the attribute as changed. This caused `[attribute]_changed?` and `changed?` methods to return true incorrectly. Example: in_time_zone 'Paris' do order = Order.new original_time = Time.local(2012, 10, 10) order.shipped_at = original_time order.save order.changed? # => false # changing value order.shipped_at = Time.local(2013, 1, 1) order.changed? # => true # reverting to original value order.shipped_at = original_time order.changed? # => false, used to return true end
* Revert "Round usec when writing timestamp attribute."Andrew White2013-01-221-15/+0
| | | | | | | | | | This reverts commit e9d2ad395ec2ef929d74752f3d71c80674044fbe. Closes #8460 Conflicts: activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb activerecord/test/cases/dirty_test.rb
* Add failing test case for #8460Andrew White2013-01-221-0/+14
| | | | Add a test case to ensure that fractional second updates are detected.
* Revert "Merge pull request #8989 from robertomiranda/use-rails-4-find-by"Guillermo Iguaran2013-01-181-7/+7
| | | | | This reverts commit 637a7d9d357a0f3f725b0548282ca8c5e7d4af4a, reversing changes made to 5937bd02dee112646469848d7fe8a8bfcef5b4c1.
* User Rails 4 find_byrobertomiranda2013-01-181-7/+7
|
* Rename update_attributes method to update, keep update_attributes as an aliasAmparo Luna + Guillermo Iguaran2013-01-031-1/+1
|
* Remove observers and sweepersRafael Mendonça França2012-11-281-1/+1
| | | | | | | | They was extracted from a plugin. See https://github.com/rails/rails-observers [Rafael Mendonça França + Steve Klabnik]
* Use assert_nil instead of assert_equalRafael Mendonça França2012-11-281-2/+2
|
* Don't call will_change! for datetime nil->"".Alisdair McDiarmid2012-11-251-0/+14
| | | | | | | Setting a nil datetime attribute to a blank string should not cause the attribute to be dirty. Fix #8310
* Fix typo in module name and make #in_time_zone privateCarlos Antonio da Silva2012-11-171-1/+1
|