aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_set
Commit message (Collapse)AuthorAgeFilesLines
* Maintain a consistent order in `ActiveRecord::Base#attributes`Sean Griffin2015-02-101-1/+11
| | | | Fixes #18871
* Remove `AttributeSet#initialized_keys`Sean Griffin2015-01-311-5/+1
| | | | | | | | | This method doesn't need to be lazy, as it is never called from reads. The only time it is called are in write cases, where we're about to loop through the results of it, and build the attribute objects anyway. So we don't gain anything by dodging the instantiation here. This is the only method that coupled `AttributeSet` to `LazyAttributeHash`, so removing it puts us back in a place where we can use a normal hash instead.
* Don't error when `attributes` is called on a frozen AR modelSean Griffin2014-12-081-1/+3
| | | | | | | | | | | | | | | | | | `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
* Remove needless call to `key?` when building attributesSean Griffin2014-11-181-2/+4
| | | | This appears to be a performance hotspot, see #17655.
* LazyAttributeHash is privateSean Griffin2014-11-181-1/+1
|
* Remove call to `key?` in `LazyAttributeHash#[]`Sean Griffin2014-11-181-5/+1
| | | | Performance improvement, as well as improved code clarity
* Remove pointless `private`Sean Griffin2014-11-171-2/+0
| | | | This class no longer has any private methods
* Don't freeze the same hash we use for memoizationSean Griffin2014-11-141-6/+7
|
* Allow `LazyAttributeHash` to be marshalledSean Griffin2014-11-141-13/+17
| | | | | | | | `default_proc` makes a hash unmarshallable, and adds unneccessary overhead. Since we control all access to the hash, let's just handle it in that method. This has the side effect of improving performance on initialization (but not neccessarily on access). We'll need to profile further once the tests are passing.
* Correctly determine if an attribute is uninitializedSean Griffin2014-11-141-1/+1
| | | | | | | 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-15/+63
| | | | | | | | | | 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.
* Revert "Improve performance of AR object instantiation"Sean Griffin2014-11-141-18/+3
| | | | | | | | | | This reverts commit 8fee923888192a658d8823b31e77ed0683dfd665. Conflicts: activerecord/lib/active_record/attribute_set/builder.rb This solution sucks, and is hard to actually apply across the board. Going to try other solutions
* Remove unneccesary default parametersSean Griffin2014-11-051-1/+1
|
* Improve performance of AR object instantiationSean Griffin2014-11-051-3/+18
| | | | | | | We introduced a performance hit by adding an additional iteration through a model's attributes on creation. We don't actually need the values from `Result` to be a hash, we can separate the columns and values and zip them up ourself during the iteration that we have to do.
* some object allocation reduction for new AR objectsAaron Patterson2014-09-271-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Benchmark: ```ruby require 'objspace' require 'active_record' ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:" ActiveRecord::Base.connection.instance_eval do create_table(:articles) { |t| t.string :name } end class Article < ActiveRecord::Base; end a = Article.create name: "foo" a = Article.find a.id N = 10 ObjectSpace::AllocationTracer.trace do N.times { Article.find a.id } end ObjectSpace::AllocationTracer.allocated_count_table table.sort_by { |_,x| x }.each do |k,v| p k => (v / N) end ```
* `Attribute` should know about its nameSean Griffin2014-06-261-4/+3
| | | | | This allows using polymorphism for the uninitialized attributes raising an exception behavior.
* Encapsulate the creation of `Attribute` objectsSean Griffin2014-06-261-1/+1
| | | | | | | | 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
* Move behavior of `read_attribute` to `AttributeSet`Sean Griffin2014-06-251-0/+33
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.