aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods/read.rb
Commit message (Collapse)AuthorAgeFilesLines
* 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
|
* Fix inspection behavior when the :id column is not primary keynamusyaka2017-02-091-1/+1
|
* Fix Rubocop violations and fix documentation visibilityRafael Mendonça França2016-12-281-1/+1
| | | | | | Some methods were added to public API in 5b14129d8d4ad302b4e11df6bd5c7891b75f393c and they should be not part of the public API.
* Privatize unneededly protected methods in Active RecordAkira Matsuda2016-12-241-2/+2
|
* Check whether the current attribute being read is aliased or not before readingPrathamesh Sonpatki2016-12-081-1/+6
| | | | | - If aliased, then use the aliased attribute name. - Fixes #26417.
* Fix broken comments indentation caused by rubocop auto-correct [ci skip]Ryuta Kamizono2016-09-141-18/+18
| | | | | | All indentation was normalized by rubocop auto-correct at 80e66cc4d90bf8c15d1a5f6e3152e90147f00772. But comments was still kept absolute position. This commit aligns comments with method definitions for consistency.
* Fix broken heredoc indentation caused by rubocop auto-correctRyuta Kamizono2016-09-031-5/+5
| | | | | | All indentation was normalized by rubocop auto-correct at 80e66cc4d90bf8c15d1a5f6e3152e90147f00772. But heredocs was still kept absolute position. This commit aligns heredocs indentation for consistency.
* applies remaining conventions across the projectXavier Noria2016-08-061-1/+0
|
* normalizes indentation and whitespace across the projectXavier Noria2016-08-061-9/+9
|
* applies new string literal convention in activerecord/libXavier Noria2016-08-061-2/+2
| | | | | The current code base is not uniform. After some discussion, we have chosen to go with double quotes by default.
* Remove unused class AttributeMethodCachePareshGupta2016-02-021-1/+0
|
* remove unused constants from activerecordPareshGupta2016-02-011-17/+6
|
* Inline uneccessary frozen string constantSean Griffin2015-08-311-3/+1
| | | | | | | We are only supporting Ruby 2.2 and later in Rails 5, so we do not need an actual constant here. Additionally, referencing a constant actually does a hash lookup (because constants are not constant in Ruby >_>). This will be marginally (likely immeasurable) faster. It is less ugly.
* Freeze string literals when not mutated.schneems2015-07-191-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I wrote a utility that helps find areas where you could optimize your program using a frozen string instead of a string literal, it's called [let_it_go](https://github.com/schneems/let_it_go). After going through the output and adding `.freeze` I was able to eliminate the creation of 1,114 string objects on EVERY request to [codetriage](codetriage.com). How does this impact execution? To look at memory: ```ruby require 'get_process_mem' mem = GetProcessMem.new GC.start GC.disable 1_114.times { " " } before = mem.mb after = mem.mb GC.enable puts "Diff: #{after - before} mb" ``` Creating 1,114 string objects results in `Diff: 0.03125 mb` of RAM allocated on every request. Or 1mb every 32 requests. To look at raw speed: ```ruby require 'benchmark/ips' number_of_objects_reduced = 1_114 Benchmark.ips do |x| x.report("freeze") { number_of_objects_reduced.times { " ".freeze } } x.report("no-freeze") { number_of_objects_reduced.times { " " } } end ``` We get the results ``` Calculating ------------------------------------- freeze 1.428k i/100ms no-freeze 609.000 i/100ms ------------------------------------------------- freeze 14.363k (± 8.5%) i/s - 71.400k no-freeze 6.084k (± 8.1%) i/s - 30.450k ``` Now we can do some maths: ```ruby ips = 6_226k # iterations / 1 second call_time_before = 1.0 / ips # seconds per iteration ips = 15_254 # iterations / 1 second call_time_after = 1.0 / ips # seconds per iteration diff = call_time_before - call_time_after number_of_objects_reduced * diff * 100 # => 0.4530373333993266 miliseconds saved per request ``` So we're shaving off 1 second of execution time for every 220 requests. Is this going to be an insane speed boost to any Rails app: nope. Should we merge it: yep. p.s. If you know of a method call that doesn't modify a string input such as [String#gsub](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37) please [give me a pull request to the appropriate file](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37), or open an issue in LetItGo so we can track and freeze more strings. Keep those strings Frozen ![](https://www.dropbox.com/s/z4dj9fdsv213r4v/let-it-go.gif?dl=1)
* Significantly improve the performance of `_read_attribute` on JRubySean Griffin2015-02-061-2/+11
| | | | | | | | | | | | | The `&block` form is more than twice as fast as the manual form of delegation (and is the code I'd rather write anyway). Unfortunately, it's still twice as slow on MRI. However, this is enough of a hotspot to justify giving JRuby special treatment. I can't currently provide benchmarks in the context of Active Record, since the JDBC adapters still aren't updated for 4.2, but the actual work performed (assuming it's been read at least once already) will have nearly the same performance characteristics as https://gist.github.com/sgrif/b86832786551aaee74de.
* fix `attribute` method scoping(i.e. private)Kuldeep Aggarwal2015-01-061-3/+1
| | | | ref #52f641264b1325a4c2bdce7971b14524bd4905f1
* replacing 'attribute' method with an aliasGeorge Millo2015-01-061-3/+2
|
* remove files which is dependent on ruby1.9 as we do not support Ruby1.9Kuldeep Aggarwal2015-01-041-22/+13
| | | | | Conflicts: activerecord/lib/active_record/attribute_methods/read.rb
* Remove `cache_attributes` and friendsRafael Mendonça França2015-01-041-11/+0
|
* Improve the performance of reading attributesSean Griffin2014-11-181-4/+10
| | | | | | | 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
|
* Avoid using heredoc for user warningsGodfrey Chan2014-08-281-3/+1
| | | | | | | | | | 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.
* 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.
* Return a null object from `AttributeSet#[]`Sean Griffin2014-06-201-4/+0
|
* Refactor in-place dirty checking to use the attribute objectSean Griffin2014-06-161-0/+4
|
* Introduce an Attribute object to handle the type casting danceSean Griffin2014-06-131-18/+9
| | | | | | | | | | | | | | | 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
* 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-091-2/+2
| | | | | | | | 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.
* Remove most code related to serialized propertiesSean Griffin2014-06-011-1/+1
| | | | | | | | | | | Nearly completely implemented in terms of custom properties. `_before_type_cast` now stores the raw serialized string consistently, which removes the need to keep track of "state". The following is now consistently true: - `model.serialized == model.reload.serialized` - A model can be dumped and loaded infinitely without changing - A model can be saved and reloaded infinitely without changing
* Rename attribute related instance variables to better express intentSean Griffin2014-05-301-5/+5
| | | | | | | | | `@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.
* Remove :timestamp column typeSean Griffin2014-05-191-2/+2
| | | | | | | | | | | | The `:timestamp` type for columns is unused. All database adapters treat them as the same database type. All code in `ActiveRecord` which changes its behavior based on the column's type acts the same in both cases. However, when the type is passed to code that checks for the `:datetime` type, but not `:timestamp` (such as XML serialization), the result is unexpected behavior. Existing schema definitions will continue to work, and the `timestamp` type is transparently aliased to `datetime`.
* Fix typo: data --> dateAlex Ghiculescu2013-12-191-1/+1
|
* Perf: avoid dupes add fallback logic for codersSam2013-09-111-7/+8
|
* method transplanting between modules isn't supported on 1.9Aaron Patterson2013-07-031-3/+26
|
* refactor the method cache objects to have a superclassAaron Patterson2013-07-031-26/+8
|
* move the reader method cache in to the read moduleAaron Patterson2013-07-031-1/+49
|
* keep a cache of the reader methods so we can reuse themAaron Patterson2013-07-031-34/+2
|
* reduce the amount of code Ruby has to parseAaron Patterson2013-07-021-3/+8
|
* making the comment more accurateAaron Patterson2013-07-021-2/+5
|
* stop storing multiple copies of a particular attribute nameAaron Patterson2013-07-021-2/+3
|
* eagerly assign the attribute name cache, remove const_missingAaron Patterson2013-07-021-0/+2
|
* Gist URLs are now namespacedAkira Matsuda2013-02-181-1/+1
| | | | see: https://github.com/blog/1406-namespaced-gists
* Don't allocate new strings in compiled attribute methodsJon Leighton2012-11-211-12/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This improves memory and performance without having to use symbols which present DoS problems. Thanks @headius and @tenderlove for the suggestion. This was originally committed in f1765019ce9b6292f2264b4601dad5daaffe3a89, and then reverted in d3494903719682abc0948bef290af0d3d7b5a440 due to it causing problems in a real application. This second attempt should solve that. Benchmark --------- require 'active_record' require 'benchmark/ips' ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') class Post < ActiveRecord::Base connection.create_table :posts, force: true do |t| t.string :name end end post = Post.create name: 'omg' Benchmark.ips do |r| r.report('Post.new') { Post.new name: 'omg' } r.report('post.name') { post.name } r.report('post.name=') { post.name = 'omg' } r.report('Post.find(1).name') { Post.find(1).name } end Before ------ Calculating ------------------------------------- Post.new 1419 i/100ms post.name 7538 i/100ms post.name= 3024 i/100ms Post.find(1).name 243 i/100ms ------------------------------------------------- Post.new 20637.6 (±12.7%) i/s - 102168 in 5.039578s post.name 1167897.7 (±18.2%) i/s - 5186144 in 4.983077s post.name= 64305.6 (±9.6%) i/s - 317520 in 4.998720s Post.find(1).name 2678.8 (±10.8%) i/s - 13365 in 5.051265s After ----- Calculating ------------------------------------- Post.new 1431 i/100ms post.name 7790 i/100ms post.name= 3181 i/100ms Post.find(1).name 245 i/100ms ------------------------------------------------- Post.new 21308.8 (±12.2%) i/s - 105894 in 5.053879s post.name 1534103.8 (±2.1%) i/s - 7634200 in 4.979405s post.name= 67441.0 (±7.5%) i/s - 337186 in 5.037871s Post.find(1).name 2681.9 (±10.6%) i/s - 13475 in 5.084511s
* Revert "Don't allocate new strings in compiled attribute methods"David Heinemeier Hansson2012-10-311-27/+12
| | | | This reverts commit f1765019ce9b6292f2264b4601dad5daaffe3a89.
* Remove ActiveRecord::ModelJon Leighton2012-10-261-7/+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.
* Don't allocate new strings in compiled attribute methodsJon Leighton2012-10-121-12/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This improves memory and performance without having to use symbols which present DoS problems. Thanks @headius and @tenderlove for the suggestion. Benchmark --------- require 'active_record' require 'benchmark/ips' ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') class Post < ActiveRecord::Base connection.create_table :posts, force: true do |t| t.string :name end end post = Post.create name: 'omg' Benchmark.ips do |r| r.report('Post.new') { Post.new name: 'omg' } r.report('post.name') { post.name } r.report('post.name=') { post.name = 'omg' } r.report('Post.find(1).name') { Post.find(1).name } end Before ------ Calculating ------------------------------------- Post.new 1419 i/100ms post.name 7538 i/100ms post.name= 3024 i/100ms Post.find(1).name 243 i/100ms ------------------------------------------------- Post.new 20637.6 (±12.7%) i/s - 102168 in 5.039578s post.name 1167897.7 (±18.2%) i/s - 5186144 in 4.983077s post.name= 64305.6 (±9.6%) i/s - 317520 in 4.998720s Post.find(1).name 2678.8 (±10.8%) i/s - 13365 in 5.051265s After ----- Calculating ------------------------------------- Post.new 1431 i/100ms post.name 7790 i/100ms post.name= 3181 i/100ms Post.find(1).name 245 i/100ms ------------------------------------------------- Post.new 21308.8 (±12.2%) i/s - 105894 in 5.053879s post.name 1534103.8 (±2.1%) i/s - 7634200 in 4.979405s post.name= 67441.0 (±7.5%) i/s - 337186 in 5.037871s Post.find(1).name 2681.9 (±10.6%) i/s - 13475 in 5.084511s
* Revert "Key the attributes hash with symbols"Jon Leighton2012-10-121-9/+5
| | | | | | | | | | | | This reverts commit 86c3dfbd47cb96af02daaa655963292b1a1b110e. Conflicts: activerecord/lib/active_record/attribute_methods/read.rb Reason: whilst this increased performance, it also presents a DoS risk via memory exhaustion if users were allowing user input to dictate the arguments of read/write_attribute. I will investigate alternative ways to cut down on string allocations here.