aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods
Commit message (Collapse)AuthorAgeFilesLines
* 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
* `update_column` take ruby-land input, not database-land inputSean Griffin2014-12-161-1/+1
| | | | | | | | | | | | | | | In the case of serialized columns, we would expect the unserialized value as input, not the serialized value. The original issue which made this distinction, #14163, introduced a bug. If you passed serialized input to the method, it would double serialize when it was sent to the database. You would see the wrong input upon reloading, or get an error if you had a specific type on the serialized column. To put it another way, `update_column` is a special case of `update_all`, which would take `['a']` and not `['a'].to_yaml`, but you would not pass data from `params` to it. Fixes #18037
* Allow custom handling of non-standard types in `time_zone_conversion`Sean Griffin2014-12-081-1/+1
| | | | | | | | | | | | PostgreSQL for example, allows infinity as a valid value for date time columns. The PG type has explicit handling for that case. However, time zone conversion will end up trampling that handling. Unfortunately, we can't call super and then convert time zones. However, if we get back nil from `.in_time_zone`, it's something we didn't expect so we can let the superclass handle it. Fixes #17971
* 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-183-6/+12
| | | | | | | 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`
* PERF: stop allocating the string "id" over and overSam2014-11-181-1/+3
|
* Reduce the amount of work performed when instantiating AR modelsSean Griffin2014-11-141-0/+1
| | | | | | | | | | We don't know which attributes will or won't be used, and we don't want to create massive bottlenecks at instantiation. Rather than doing *any* iteration over types and values, we can lazily instantiate the object. The lazy attribute hash should not fully implement hash, or subclass hash at any point in the future. It is not meant to be a replacement, but instead implement its own interface which happens to overlap.
* Use `DelegateClass` instead of `SimpleDelegator` for type decoratorsSean Griffin2014-11-141-1/+1
| | | | There is a significant performance difference between the two. Closes
* let's warn with heredocsXavier Noria2014-10-281-2/+6
| | | | | | | | | | | | The current style for warning messages without newlines uses concatenation of string literals with manual trailing spaces where needed. Heredocs have better readability, and with `squish` we can still produce a single line. This is a similar use case to the one that motivated defining `strip_heredoc`, heredocs are super clean.
* test, better describe `SerializationTypeMismatch` behavior. refs #14716.Yves Senn2014-10-161-2/+2
|
* docs, since #16702 we detect mutation on serialized attributes. [ci skip]Yves Senn2014-10-161-3/+0
| | | | /cc @sgrif
* Allow YAML serialization when using TZ aware attributesSean Griffin2014-09-171-0/+2
|
* Merge pull request #16704 from ankit1910/use-existing-methodRafael Mendonça França2014-09-011-1/+1
|\ | | | | use self instead of #read_attribute
| * use self instead of #read_attributeankit19102014-08-261-1/+1
| |
* | Avoid using heredoc for user warningsGodfrey Chan2014-08-282-7/+4
| | | | | | | | | | | | | | | | | | | | Using heredoc would enforce line wrapping to whatever column width we decided to use in the code, making it difficult for the users to read on some consoles. This does make the source code read slightly worse and a bit more error-prone, but this seems like a fair price to pay since the primary purpose for these messages are for the users to read and the code will not stick around for too long.
* | 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
|
* Define id_was to get the previous value of the primary keyRafael Mendonça França2014-08-061-1/+7
| | | | | | | | | Currently when we call id_was and we have a custom primary key name Active Record will return the current value of the primary key. This make impossible to correctly do an update operation if you change the id. Fixes #16413
* Merge pull request #16180 from rafaelfranca/rm-dirtyRafael Mendonça França2014-07-151-2/+2
|\ | | | | Improve Active Model Dirty API.
| * 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.
* | Revert "Revert "Merge pull request #16059 from jenncoop/json-serialized-attr""Godfrey Chan2014-07-151-1/+6
|/ | | | | | | This reverts commit 6f3c64eeb1dc8288dae49f114aaf619adc7dcb7f. Conflicts: activerecord/CHANGELOG.md
* Revert "Merge pull request #16059 from jenncoop/json-serialized-attr"Godfrey Chan2014-07-051-6/+1
| | | | | | This reverts commit a03097759bd7103bb9db253e7ba095f011453f75. This needs more work before it would work correctly on master.
* Merge pull request #16059 from jenncoop/json-serialized-attrGodfrey Chan2014-07-051-1/+6
| | | | | | | | Fixed issue with ActiveRecord serialize object as JSON Conflicts: activerecord/CHANGELOG.md activerecord/lib/active_record/attribute_methods/serialization.rb
* Stop using instance exec for type decoratorsSean Griffin & Sean Doyle2014-06-271-5/+15
| | | | | | | | We are moving this behavior out to an object that we would like to keep separated from `ActiveRecord::Base`, which means not passing the class object to it. As such, we need to stop using `instance_exec`, and instead close over the subclass on global type decorators that are applied in `Base`.
* Move writing unknown column exception to null attributeSean Griffin2014-06-262-9/+2
| | | | | | Making this change revealed several subtle bugs related to models with no primary key, and anonymous classes. These have been fixed as well, with regression tests added.
* Encapsulate the creation of `Attribute` objectsSean Griffin2014-06-261-3/+2
| | | | | | | | This will make it less painful to add additional properties, which should persist across writes, such as `name`. Conflicts: activerecord/lib/active_record/attribute_set.rb
* Merge pull request #15868 from sgrif/sg-uninitialized-attributesRafael Mendonça França2014-06-261-10/+3
|\ | | | | | | | | | | | | | | Move behavior of `read_attribute` to `AttributeSet` Conflicts: activerecord/lib/active_record/attribute_set.rb activerecord/test/cases/attribute_set_test.rb
| * Move behavior of `read_attribute` to `AttributeSet`Sean Griffin2014-06-251-10/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Moved `Builder` to its own file, as it started looking very weird once I added private methods to the `AttributeSet` class and the `Builder` class started to grow. Would like to refactor `fetch_value` to change to ```ruby self[name].value(&block) ``` But that requires the attributes to know about their name, which they currently do not.
* | Merge pull request #15846 from sgrif/sg-attributes-before-type-castRafael Mendonça França2014-06-261-1/+1
|\ \ | | | | | | | | | | | | | | | | | | | | | Move `attributes_before_type_cast` to `AttributeSet` Conflicts: activerecord/lib/active_record/attribute_set.rb activerecord/test/cases/attribute_set_test.rb
| * | Move `attributes_before_type_cast` to `AttributeSet`Sean Griffin2014-06-211-1/+1
| | |
* | | Silence warning in testSean Griffin2014-06-241-2/+2
| |/ |/| | | | | | | We still had one file using `column_for_attribute` when it could return nil, causing deprecation warnings in the tests.
* | Return a null object from `AttributeSet#[]`Sean Griffin2014-06-203-10/+4
|/
* 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.
* Promote time zone aware attributes to a first class type decoratorSean Griffin2014-06-161-1/+6
| | | | | | | | | | | | | This refactoring revealed the need for another form of decoration, which takes a proc to select which it applies to (There's a *lot* of cases where this form can be used). To avoid duplication, we can re-implement the old decoration in terms of the proc-based decoration. The reason we're `instance_exec`ing the matcher is for cases such as time zone aware attributes, where a decorator is defined in a parent class, and a method called in the matcher is overridden by a child class. The matcher will close over the parent, and evaluate in its context, which is not the behavior we want.
* Refactor in-place dirty checking to use the attribute objectSean Griffin2014-06-162-9/+7
|
* Change the deprecation warning on `serialized_attributes`Sean Griffin2014-06-151-8/+2
| | | | to "without replacement"
* Deprecate `serialized_attributes` without replacementSean Griffin2014-06-141-16/+17
| | | | | We've stopped using it internally, in favor of polymorphism. So should you!
* Merge pull request #15674 from sgrif/sg-mutable-attributesMatthew Draper2014-06-142-23/+77
|\ | | | | Detect in-place changes on mutable AR attributes
| * Detect in-place changes on mutable AR attributesSean Griffin2014-06-132-23/+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.
* | Merge pull request #15593 from sgrif/sg-attributeRafael Mendonça França2014-06-133-29/+19
|\ \ | | | | | | Introduce an Attribute object to handle the type casting dance
| * | Introduce an Attribute object to handle the type casting danceSean Griffin2014-06-133-29/+19
| |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | There's a lot more that can be moved to these, but this felt like a good place to introduce the object. Plans are: - Remove all knowledge of type casting from the columns, beyond a reference to the cast_type - Move type_cast_for_database to these objects - Potentially make them mutable, introduce a state machine, and have dirty checking handled here as well - Move `attribute`, `decorate_attribute`, and anything else that modifies types to mess with this object, not the columns hash - Introduce a collection object to manage these, reduce allocations, and not require serializing the types
* | Use a conditional rather than early return in `id`Sean Griffin2014-06-121-3/+4
| |
* | Fix performance regression on preloading HABTM associationsSean Griffin2014-06-121-0/+1
|/ | | | | | | | | | | We'd spend a lot of time calling `hash` and `eql?` on the join model, which has no primary key. Calling `id` with no primary key is a really slow way to get back `nil`, so we can improve the performance there. However, even with the escape clause, we *still* weren't getting high enough performance, as we were checking the primary key too much. `hash` will always return `nil.hash` for records with no id, and `==` will always return `false`. We can optimize those cases in the HABTM join model.
* rm cached attributesSean Griffin2014-06-111-38/+11
| | | | | | | | | | The original patch that added this concept can be found [here](https://web.archive.org/web/20090601022739/http://dev.rubyonrails.org/ticket/9767). The current default behavior is to cache everything except serialized columns, unless the user specified otherwise. If anyone were to specify otherwise, many types would actually be completely broken. Still, the method is left in place with a deprecation warning in case anyone is actually still calling this method.
* Rename `type_cast` to `type_cast_from_database`Sean Griffin2014-06-092-3/+3
| | | | | | | | In some cases there is a difference between the two, we should always be doing one or the other. For convenience, `type_cast` is still a private method on type, so new types that do not need different behavior don't need to implement two methods, but it has been moved to private so it cannot be used accidentally.
* Make `_before_type_cast` actually be before type castSean Griffin2014-06-092-46/+15
| | | | | | | | | | | | | - 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
* Merge pull request #15546 from sgrif/sg-lazy-decoratorsRafael Mendonça França2014-06-071-4/+2
|\ | | | | Don't query the database schema when calling `serialize`
| * Don't query the database schema when calling `serialize`Sean Griffin2014-06-071-4/+2
| | | | | | | | | | | | We need to decorate the types lazily. This is extracted to a separate API, as there are other refactorings that will be able to make use of it, and to allow unit testing the finer points more granularly.
* | Merge pull request #15561 from sgrif/sg-time-zone-aware-arraysRafael Mendonça França2014-06-071-1/+11
|\ \ | | | | | | Ensure time zones don't change after round trip with array columns