| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
| |
destroy
|
|
|
|
| |
create
|
|\
| |
| | |
Idempotent counter caches, fix concurrency issues with counter caches
|
| | |
|
| | |
|
|/ |
|
|\
| |
| |
| |
| |
| |
| | |
Fix insertion of records for hmt association with scope
Conflicts:
activerecord/CHANGELOG.md
|
| | |
|
| |
| |
| |
| |
| | |
Passing in a blank string is a bug so there's no reason
to check for a blank string.
|
| |
| |
| |
| |
| |
| |
| | |
This method no longer returns an array of all records that
have been removed. Correct documentation to reflect this change.
See issue 14546
|
|\ \
| | |
| | |
| | | |
Renamed private methods _create_record and _update_record
|
| | |
| | |
| | |
| | |
| | |
| | | |
This is to ensure that they are not accidentally called by the app code.
They are renamed to _create_record and _update_record respectively.
Closes #11645
|
| | |
| | |
| | |
| | |
| | |
| | | |
CollectionProxy should be able to reuse the behavior (methods) of its parent class,
but with its own state. This change allows CollectionProxy to use the arel object
corresponding to its association's scope.
|
|\ \ \
| | | |
| | | |
| | | |
| | | | |
eileencodes/fix_delete_all_to_not_use_IN_statement
Fix delete all to not produce sql in statement
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
When delete_all is run on a CollectionProxy and has a
dependency of delete_all the SQL that is produced has an IN
statement. (DELETE FROM `associated_model` where `associated_model`
.`parent_id` = 1 AND `associated_model`.`id` IN (1, 2, 3...)).
This only happens if the association is not loaded (both loaded
and non-loaded delete_all should behave the same. This is a huge
problem when it comes to deleting many records because the query
becomes very slow. Instead the SQL produced should be (DELETE FROM
`assoicated_model` where `associated_model`.`parent_model_id`=1).
I fixed this by making sure the check for loaded and destroy also
makes sure that the dependent is not delete_all, so the conditional
goes to the else and deletes the records directly without the IN
statement.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The new method relies on AR::Associations::Association knowing about both reflection and a model class.
AR::Base#association now raises a descriptive error when trying to access non-existent associations. Previously it would blow up with a confusing NoMethodError: undefined method `association_class' for nil:NilClass.
|
|/ / /
| | |
| | |
| | | |
Defer to Association#klass instead of having a custom/duplicate code.
|
|\ \ \
| | | |
| | | | |
Pass a base relation to build_default_scope when joining
|
| | | |
| | | |
| | | |
| | | |
| | | | |
This allows the default scope to be built using the current table alias.
Resolves #12770
|
| | | | |
|
| | | |
| | | |
| | | |
| | | |
| | | | |
Pass the id of the object to the method by calling `.id` on the AR
object.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Apparently we've been using a buggy feature for the past 6 years:
https://bugs.ruby-lang.org/issues/9593
|
| | | | |
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
When replacing a has_many association with the same one, there is no
need to do a round-trip to the db to create/and drop a new transaction.
[fixes #14220]
|
|/ / /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
`before_add` callbacks are fired before the record is saved on
`has_and_belongs_to_many` assocations *and* on `has_many :through`
associations. Before this change, `before_add` callbacks would be fired
before the record was saved on `has_and_belongs_to_many` associations, but
*not* on `has_many :through` associations.
Fixes #14144
|
| | | |
|
|/ /
| |
| |
| |
| |
| |
| |
| | |
constructor"
This reverts commit f9e4c3c7c0c4152b62fe9202a9d12262884bb118.
[fixes #14116]
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
If we know the alias tracker is empty, we can create one that doesn't
use a hash with default block for counting.
ActiveRecord::Base.establish_connection(adapter: 'sqlite3',
database: ':memory:')
ActiveRecord::Schema.define do
create_table :posts, force: true do |t|
t.integer :comments_count
end
create_table :comments, force: true do |t|
t.integer :post_id
end
end
class Post < ActiveRecord::Base; has_many :comments; end
class Comment < ActiveRecord::Base; belongs_to :post, counter_cache: true; end
10.times { Comment.create!(post: Post.create!) }
record = Post.first
association_name = :comments
Benchmark.ips do |x|
reflection = record.class.reflect_on_association(association_name)
association = reflection.association_class.new(record, reflection)
x.report('assoc') do
reflection.association_class.new(record, reflection)
end
x.report('reader') do
association.reader;nil
end
x.report('combined') do
reflection.association_class.new(record, reflection).reader;nil
end
end
[aaron@higgins rails (tracker)]$ TEST=ips bundle exec ruby ../1bb5456b5e035343df9d/gistfile1.rb
-- create_table(:posts, {:force=>true})
-> 0.0062s
-- create_table(:comments, {:force=>true})
-> 0.0003s
Calculating -------------------------------------
assoc 833 i/100ms
reader 28703 i/100ms
combined 839 i/100ms
-------------------------------------------------
assoc 9010.3 (±3.8%) i/s - 44982 in 5.000022s
reader 3214523.4 (±5.5%) i/s - 16016274 in 5.001136s
combined 8841.0 (±5.8%) i/s - 44467 in 5.049269s
[aaron@higgins rails (tracker)]$ TEST=ips bundle exec ruby ../1bb5456b5e035343df9d/gistfile1.rb
-- create_table(:posts, {:force=>true})
-> 0.0060s
-- create_table(:comments, {:force=>true})
-> 0.0003s
Calculating -------------------------------------
assoc 888 i/100ms
reader 29217 i/100ms
combined 900 i/100ms
-------------------------------------------------
assoc 9674.3 (±3.3%) i/s - 48840 in 5.054022s
reader 2988474.8 (±6.9%) i/s - 14842236 in 4.998230s
combined 9674.0 (±3.1%) i/s - 48600 in 5.028694s
|
| | |
|
| | |
|
| |
| |
| |
| |
| | |
This helps with our sanity. The class is internal, we can refactor to a
"nice" API later.
|
| |
| |
| |
| |
| | |
AssociationScope no longer maintains state, so we're safe to keep a
singleton and save on GC time
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
|\ \
| | |
| | |
| | |
| | | |
Fortisque/kevin/active_record_HABTM_with_belongs_to
destruction errors out on HABTM w/out primary key
|
| | | |
|
|/ / |
|