aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/attribute_set_test.rb
Commit message (Collapse)AuthorAgeFilesLines
* Fix RuboCop offensesKoichi ITO2017-08-161-1/+1
| | | | And enable `context_dependent` of Style/BracesAroundHashParameters cop.
* Use frozen-string-literal in ActiveRecordKir Shatrov2017-07-191-0/+2
|
* Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"Matthew Draper2017-07-021-1/+0
| | | | | This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
* Enforce frozen string in RubocopKir Shatrov2017-07-011-0/+1
|
* "Use assert_nil if expecting nil. This will fail in minitest 6."Akira Matsuda2016-12-251-1/+1
|
* remove redundant curlies from hash argumentsXavier Noria2016-08-061-1/+1
|
* applies new string literal convention in activerecord/testXavier Noria2016-08-061-21/+21
| | | | | The current code base is not uniform. After some discussion, we have chosen to go with double quotes by default.
* Implement equality comparison on `AttributeSet` and friendsSean Griffin2015-10-061-0/+10
| | | | | | | Any gems or libraries which do work with serialization or YAML will ultimately need to compare these objects (albeit indirectly) to ensure correctness. These will likely never get used internally (as they're slow), but we should still expose them for others.
* Separate `dup` from `deep_dup` in the attributes hashSean Griffin2015-09-281-1/+19
| | | | | | | | | | | I'm looking to move towards a tree-like structure for dirty checking that involves an attribute holding onto the attribute that it was created from. This means that `changed?` can be fully encapsulated on that object. Since the objects are immutable, in `changes_applied`, we can simply perform a shallow dup, instead of a deep one. I'm not sure if that will actually end up in a performance boost, but I'd like to semantically separate these concepts regardless
* Clean up the implementation of AR::DirtySean Griffin2015-09-241-0/+14
| | | | | | | | | | | | | This moves a bit more of the logic required for dirty checking into the attribute objects. I had hoped to remove the `with_value_from_database` stuff, but unfortunately just calling `dup` on the attribute objects isn't enough, since the values might contain deeply nested data structures. I think this can be cleaned up further. This makes most dirty checking become lazy, and reduces the number of object allocations and amount of CPU time when assigning a value. This opens the door (but doesn't quite finish) to improving the performance of writes to a place comparable to 4.1
* `type_cast_from_user` -> `cast`Sean Griffin2015-02-171-1/+1
|
* `Type#type_cast_from_database` -> `Type#deserialize`Sean Griffin2015-02-171-1/+1
|
* Maintain a consistent order in `ActiveRecord::Base#attributes`Sean Griffin2015-02-101-0/+10
| | | | Fixes #18871
* Introduce `ActiveRecord::Base#accessed_fields`Sean Griffin2015-01-201-0/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This method can be used to see all of the fields on a model which have been read. This can be useful during development mode to quickly find out which fields need to be selected. For performance critical pages, if you are not using all of the fields of a database, an easy performance win is only selecting the fields which you need. By calling this method at the end of a controller action, it's easy to determine which fields need to be selected. While writing this, I also noticed a place for an easy performance win internally which I had been wanting to introduce. You cannot mutate a field which you have not read. Therefore, we can skip the calculation of in place changes if we have never read from the field. This can significantly speed up methods like `#changed?` if any of the fields have an expensive mutable type (like `serialize`) ``` Calculating ------------------------------------- #changed? with serialized column (before) 391.000 i/100ms #changed? with serialized column (after) 1.514k i/100ms ------------------------------------------------- #changed? with serialized column (before) 4.243k (± 3.7%) i/s - 21.505k #changed? with serialized column (after) 16.789k (± 3.2%) i/s - 84.784k ```
* Don't error when `attributes` is called on a frozen AR modelSean Griffin2014-12-081-0/+8
| | | | | | | | | | | | | | | | | | `freeze` will ultimately end up freezing the `AttributeSet`, which in turn freezes its `@attributes` hash. However, we actually insert a special object to lazily instantiate the values of the hash on demand. When it does need to actually instantiate all of them for iteration (the only case is `ActiveRecord::Base#attributes`, which calls `AttributeSet#to_h`), it will set an instance variable as a performance optimization Since it's just an optimization for subsequent calls, and that method being called at all is a very uncommon case, we can just leave the ivar alone if we're frozen, as opposed to coming up with some overly complicated mechanism for freezing which allows us to continue to modify ourselves. Fixes #17960
* Correctly determine if an attribute is uninitializedSean Griffin2014-11-141-1/+9
| | | | | | | In real usage, we give the builder a types hash with a default value of `Type::Value.new`. This means we need to explicitly check for the key, rather than the truthiness of the type to determine if it's a known but uninitialized attribute
* Reduce the amount of work performed when instantiating AR modelsSean Griffin2014-11-141-0/+9
| | | | | | | | | | 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.
* AttributeSet#include? -> AttributeSet#key?Sean Griffin2014-07-111-5/+5
| | | | https://github.com/rails/rails/pull/15868/files#r14135210
* `Attribute` should know about its nameSean Griffin2014-06-261-0/+3
| | | | | This allows using polymorphism for the uninitialized attributes raising an exception behavior.
* Encapsulate the creation of `Attribute` objectsSean Griffin2014-06-261-1/+35
| | | | | | | | 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-0/+56
|\ | | | | | | | | | | | | | | 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-0/+56
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-0/+7
|\ \ | |/ |/| | | | | | | | | | | 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-0/+7
| |
* | Merge pull request #15839 from sgrif/sg-attr-set-nullYves Senn2014-06-221-0/+8
|\ \ | | | | | | Return a null object from `AttributeSet#[]`
| * | Return a null object from `AttributeSet#[]`Sean Griffin2014-06-201-0/+8
| |/
* / Move `attributes` to the `AttributeSet` object.Sean Griffin2014-06-211-0/+8
|/
* Introduce an object to aid in creation and management of `@attributes`Sean Griffin2014-06-191-0/+49
Mostly delegation to start, but we can start moving a lot of behavior in bulk to this object.