| Commit message (Collapse) | Author | Age | Files | Lines |
|\
| |
| |
| |
| | |
Conflicts:
guides/source/migrations.md
|
| | |
|
| | |
|
|/
|
|
| |
Closes #3313
|
|\
| |
| |
| |
| | |
Conflicts:
guides/source/active_record_validations.md
|
| | |
|
| |
| |
| |
| | |
skip]
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
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.
|
|/
|
|
|
| |
These are for internal use only and cannot be relied on as part of the
public API. See discussion on 8c2c60511beaad05a218e73c4918ab89fb1804f0.
|
|
|
|
|
|
|
| |
To perform a sum calculation over the array of elements, use to_a.sum(&block).
Please check the discussion in f9cb645dfcb5cc89f59d2f8b58a019486c828c73
for more context.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This reverts commit f9cb645dfcb5cc89f59d2f8b58a019486c828c73.
Conflicts:
activerecord/CHANGELOG.md
Revert "Allow blocks for count with ActiveRecord::Relation. Document and test that sum allows blocks"
This reverts commit 9cc2bf69ce296b7351dc612a8366193390a305f3.
Conflicts:
activerecord/lib/active_record/relation/calculations.rb
|
| |
|
|\
| |
| |
| |
| | |
Conflicts:
actionpack/lib/action_dispatch/routing/redirection.rb
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
| |
| |
| | |
Closes #7551
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
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.)
|
| | |
|
| | |
|
| |
| |
| |
| |
| | |
This is already handled by #find, it's a duplicate check, since
find_with_ids is not called from anywhere else.
|
|/ |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
| |
|
|
|
|
| |
allocations
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Before:
Calculating -------------------------------------
ar 87 i/100ms
-------------------------------------------------
ar 823.4 (±11.8%) i/s - 4089 in 5.070234s
After:
Calculating -------------------------------------
ar 88 i/100ms
-------------------------------------------------
ar 894.1 (±3.9%) i/s - 4488 in 5.028161s
Same test as 3a6dfca7f5f5bd45cea2f6ac348178e72423e1d5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
before:
Calculating -------------------------------------
ar 83 i/100ms
-------------------------------------------------
ar 832.1 (±4.0%) i/s - 4233 in 5.096611s
after:
Calculating -------------------------------------
ar 87 i/100ms
-------------------------------------------------
ar 839.0 (±9.3%) i/s - 4176 in 5.032782s
Benchmark:
require 'config/environment'
require 'benchmark/ips'
GC.disable
unless User.find_by_login('tater')
u = User.new
u.login = 'tater'
u.save!
end
def active_record
user = User.find_by_login('tater')
starred = user.starred_items.count
end
active_record
Benchmark.ips do |x|
x.report("ar") { active_record }
end
|
| |
|
| |
|
| |
|
|
|
|
|
| |
Related to 761bc751d31c22e2c2fdae2b4cdd435b68b6d783 and
eb876c4d07130f15be2cac7be968cc393f959c62
|
|
|
|
|
|
|
| |
This reverts commit 761bc751d31c22e2c2fdae2b4cdd435b68b6d783.
This commit wasn't fixing any issue just using the same table for
different models with different primary keys.
|
| |
|
|
|
|
| |
Closes #6960
|
| |
|
|
|
|
|
|
|
|
|
| |
In some circumstances engine was Arel::Table.engine which for separate
reasons was an ActiveRecord::Model::DeprecationProxy, which caused a
deprecation warning.
In any case, we want the actual model class here, since we want to use
it to infer information about associations.
|
| |
|
|
|
|
|
| |
Previously the reflection would be looked up on the wrong class. However
the test passed because the examples referred back to themselves.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Allows you to specify the model association key in a belongs_to
relationship instead of the foreign key.
The following queries are now equivalent:
Post.where(:author_id => Author.first)
Post.where(:author => Author.first)
PriceEstimate.where(:estimate_of_type => 'Treasure', :estimate_of_id => treasure)
PriceEstimate.where(:estimate_of => treasure)
|
| |
|
|
|
|
|
|
| |
This is a cleaner version of #6916.
Closes #3165.
|
|
|
|
|
|
| |
This is a real fix (as compared to the band-aid in b127d86c), which uses
the recently-added equality methods for ARel nodes. It has the side
benefit of simplifying the merge code a bit.
|
|
|
|
|
|
|
|
|
| |
This is at best a band-aid for a more proper fix, since it won't truly
handle the removal of the previous equality condition of these other
nodes. I'm planning to put in some work on ARel toward supporting that
goal.
Related: rails/arel#130, ernie/squeel#153, ernie/squeel#156
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This was requested by DHH to allow creating of one's own custom
association macros.
For example:
module Commentable
def has_many_comments(extra)
has_many :comments, -> { where(:foo).merge(extra) }
end
end
class Post < ActiveRecord::Base
extend Commentable
has_many_comments -> { where(:bar) }
end
|
| |
|