aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation/delegation.rb
Commit message (Collapse)AuthorAgeFilesLines
...
* Add methods to array delegation from `Relation`Kevin Dougherty2016-02-191-1/+2
| | | | | | | | | | Delegation of some `Array` methods was removed in commit 9d79334. That change did add explicit delegation of a few methods that `Array` has but which aren't on `Enumerable`. However, a few non-mutation methods were omitted. This adds `Array` delegation of `#in_groups`, `#in_groups_of`, `#shuffle` and `#split`. This allows things like `MyThing.all.in_groups_of(3) { ... }` to continue working as they did before commit 9d79334.
* Ensure `Relation` responds to `shuffle`Sean Griffin2015-12-011-1/+1
| | | | | It appears that I missed this one when I delegated all the non-mutation array methods that were not on Enumerable
* Remove blanket array delegation from `Relation`Sean Griffin2015-11-231-14/+2
| | | | | | | | | As was pointed out by #17128, our blacklist of mutation methods was non-exhaustive (and would need to be kept up to date with each new version of Ruby). Now that `Relation` includes `Enumerable`, the number of methods that we actually need to delegate are pretty small. As such, we can change to explicitly delegating the few non-mutation related methods that `Array` has which aren't on `Enumerable`
* docs, nodoc internal Active Record `DelegateCache`. [ci skip]Yves Senn2015-10-131-3/+3
|
* 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)
* Allow Relation#compact using delegationJordan Raine2015-05-281-1/+1
|
* Remove unneeded `require 'as/deprecation'`claudiob2015-01-041-1/+0
| | | | | Tests should still pass after removing `require 'active_support/deprecation'` from these files since the related deprecations have been removed.
* Put back Relation#join method as a delegate to ArrayBogdan Gusiev2014-05-051-1/+1
| | | | | | | | This is a regression 4.0 -> 4.1 fix. In 4.1.0 Relation#join is delegated to Arel#SelectManager. In 4.0 series it is delegated to Array#join This patch puts back the behaviour of 4.0
* select! renamed to avoid name collision Array#select!Earl J St Sauver2014-04-211-1/+1
| | | | | | | | Fixes #14752 Select mimics the block interface of arrays, but does not mock the block interface for select!. This change moves the api to be a private method, _select!.
* Create a blacklist to disallow mutator methods to be delegated to `Array`.Lauro Caetano2013-12-171-11/+14
| | | | | | | | This change was necessary because the whitelist wouldn't work. It would be painful for users trying to update their applications. This blacklist intent to prevent odd bugs and confusion in code that call mutator methods directely on the `Relation`.
* argument prefix warning removedArun Agrawal2013-12-131-1/+1
| | | | * interpreted as a argument prefix
* Add a bunch of Relation -> Array delegate methods to the whitelist. This ↵Jeremy Kemper2013-12-121-4/+12
| | | | won't last - aim to switch back to a blacklist for mutator methods.
* Use `public_send` instead of just use `send`.Lauro Caetano2013-12-121-5/+5
|
* Use a whitelist to delegate methods to arrayLauro Caetano2013-12-121-18/+6
|
* Deprecate the delegation of Array bang methods in ActiveRecord::DelegationBen Woosley2013-09-041-3/+14
| | | | | | | | | | | The primary means of returning results for Array bang methods is to modify the array in-place. When you call these methods on a relation, that array is created, modified, and then thrown away. Only the secondary return value is exposed to the caller. Removing this delegation is a straight-forward way to reduce user error by forcing callers to first explicitly call #to_a in order to expose the array to be acted on by the bang method.
* no need to fully qualifyAaron Patterson2013-08-301-1/+1
|
* move the cache to the AR models and populate it on inheritedAaron Patterson2013-08-301-20/+29
|
* no need for the const_get since we lockAaron Patterson2013-08-301-5/+1
|
* require a class for cache computationsAaron Patterson2013-08-301-1/+3
|
* cache misses should return selfAaron Patterson2013-08-301-1/+1
|
* stop relying on side effects of const_missingAaron Patterson2013-07-231-7/+7
|
* add a specific factory method rather than using newAaron Patterson2013-07-231-4/+2
|
* add missing :nodoc: marks to ActiveRecord::Delegation [ci skip]Francesco Rodriguez2013-04-291-3/+3
|
* Use define_method when method name contains weird characters.Krzysztof Jurewicz2013-03-181-5/+3
|
* remove AR auto-explain (config.auto_explain_threshold_in_seconds)Yves Senn2013-02-241-1/+1
| | | | | | | | | | We discussed that the auto explain feature is rarely used. This PR removes only the automatic explain. You can still display the explain output for any given relation using `ActiveRecord::Relation#explain`. As a side-effect this should also fix the connection problem during asset compilation (#9385). The auto explain initializer in the `ActiveRecord::Railtie` forced a connection.
* These are already required through AS/railsAkira Matsuda2013-01-071-1/+0
| | | | | | * dependencies/autoload * concern * deprecation
* Replace some global Hash usages with the new thread safe cache.thedarkone2012-12-141-22/+16
| | | | | | | | | | | | | | | | Summary of the changes: * Add thread_safe gem. * Use thread safe cache for digestor caching. * Replace manual synchronization with ThreadSafe::Cache in Relation::Delegation. * Replace @attribute_method_matchers_cache Hash with ThreadSafe::Cache. * Use TS::Cache to avoid the synchronisation overhead on listener retrieval. * Replace synchronisation with TS::Cache usage. * Use a preallocated array for performance/memory reasons. * Update the controllers cache to the new AS::Dependencies::ClassCache API. The original @controllers cache no longer makes much sense after @tenderlove's changes in 7b6bfe84f3 and f345e2380c. * Use TS::Cache in the connection pool to avoid locking overhead. * Use TS::Cache in ConnectionHandler.
* Use separate Relation subclasses for each AR classJon Leighton2012-11-301-32/+100
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | At present, ActiveRecord::Delegation compiles delegation methods on a global basis. The compiled methods apply to all subsequent Relation instances. This creates several problems: 1) After Post.all.recent has been called, User.all.respond_to?(:recent) will be true, even if User.all.recent will actually raise an error due to no User.recent method existing. (See #8080.) 2) Depending on the AR class, the delegation should do different things. For example, if a Post.zip method exists, then Post.all.zip should call it. But this will then result in User.zip being called by a subsequent User.all.zip, even if User.zip does not exist, when in fact User.all.zip should call User.all.to_a.zip. (There are various variants of this problem.) We are creating these compiled delegations in order to avoid method missing and to avoid repeating logic on each invocation. One way of handling these issues is to add additional checks in various places to ensure we're doing the "right thing". However, this makes the compiled methods signficantly slower. In which case, there's almost no point in avoiding method_missing at all. (See #8127 for a proposed solution which takes this approach.) This is an alternative approach which involves creating a subclass of ActiveRecord::Relation for each AR class represented. So, with this patch, Post.all.class != User.all.class. This means that the delegations are compiled for and only apply to a single AR class. A compiled method for Post.all will not be invoked from User.all. This solves the above issues without incurring significant performance penalties. It's designed to be relatively seamless, however the downside is a bit of complexity and potentially confusion for a user who thinks that Post.all and User.all should be instances of the same class. Benchmark --------- require 'active_record' require 'benchmark/ips' class Post < ActiveRecord::Base establish_connection adapter: 'sqlite3', database: ':memory:' connection.create_table :posts def self.omg :omg end end relation = Post.all Benchmark.ips do |r| r.report('delegation') { relation.omg } r.report('constructing') { Post.all } end Before ------ Calculating ------------------------------------- delegation 4392 i/100ms constructing 4780 i/100ms ------------------------------------------------- delegation 144235.9 (±27.7%) i/s - 663192 in 5.038075s constructing 182015.5 (±21.2%) i/s - 850840 in 5.005364s After ----- Calculating ------------------------------------- delegation 6677 i/100ms constructing 6260 i/100ms ------------------------------------------------- delegation 166828.2 (±34.2%) i/s - 754501 in 5.001430s constructing 116575.5 (±18.6%) i/s - 563400 in 5.036690s Comments -------- Bear in mind that the standard deviations in the above are huge, so we can't compare the numbers too directly. However, we can conclude that Relation construction has become a little slower (as we'd expect), but not by a huge huge amount, and we can still construct a large number of Relations quite quickly.
* Make ActiveRecord::Delegation#method_missing threadsafeJon Leighton2012-11-101-3/+21
| | | | | | | | | | | | Two threads may be in method_missing at the same time. If so, they might both try to define the same delegator method. Such a situation probably wouldn't result in a particularly spectacular bug as one method would probably just be overridden by an identical method, but it could cause warnings to pop up. (It could be worse if method definition is non-atomic in a particular implementation.) (We will also need this mutex shortly anyway, see #8127.)
* load active_support/core_ext/module/delegation in active_support/railsXavier Noria2012-08-021-1/+0
|
* Add nodocs to delegation module and docs for merge!Oscar Del Ben2012-07-171-1/+1
|
* Fix #6635. We should call Scoping methods, before calling Array methods.kennyj2012-06-101-5/+5
|
* Do not raise an exception if an invalid route was generated automatically.José Valim2011-12-161-1/+1
|
* Set up delegations also for to_a and arel branches.José Valim2011-12-151-2/+9
|
* Move delegation reponsibilities of Relation to a module. Also precompile ↵José Valim2011-12-151-0/+42
method missing calls for rofscale.