Previously we only provided a method to set the ignored schema cache
tables, but there was no way to ask if a table was ignored by the schema
cache. Applications may want to implement their own schema cache, or at
least run this check. Rather than forcing them to implement an internal
method, this adds a way to ask whether a table is ignored by the schema
cache code.
Usage:
```ruby
ActiveRecord.schema_cache_ignored_tables = ["developers"]
ActiveRecord.schema_cache_ignored_tables?("developers")
```
PostgreSQL Cidr#change? raise an error of NoMethodError: undefined method `prefix' for nil, when creating a record with an empty value of inet/cidr column.
Fix: https://github.com/rails/rails/issues/51807
`association_cached?` only means the Association object was
created, not that the records were loaded.
Co-Authored-By: benk-gc <bkyriakou@gocardless.com>
Ref: https://github.com/rails/rails/pull/50396
Ref: https://github.com/rails/rails/pull/51776
`ActiveRecord::Relation` automatically delegates missing methods
to the model class wrapped in a `scoping { }` block.
This is to support scoping in user defined class methods. The problem
however is that it's very error prone for the framework, because we
can mistakenly call model methods from inside `Relation` and not
realized we're applying a global scope.
In the best case scenario it's just a waste of performance, but
it can also lead to bugs like https://github.com/rails/rails/issues/51775
I'm planning to restrict this automatic delegation to methods defined
in childs of `ActiveRecord::Base` only: https://github.com/rails/rails/pull/50396
but for this to work we must first refactor any Rails code that rely on it.
Ref: https://github.com/rails/rails/pull/50396
Ref: https://github.com/rails/rails/pull/51776
`ActiveRecord::Relation` automatically delegates missing methods
to the model class wrapped in a `scoping { }` block.
This is to support scoping in user defined class methods. The problem
however is that it's very error prone for the framework, because we
can mistakenly call model methods from inside `Relation` and not
realized we're applying a global scope.
In the best case scenario it's just a waste of performance, but
it can also lead to bugs like https://github.com/rails/rails/issues/51775
I'm planning to restrict this automatic delegation to methods defined
in childs of `ActiveRecord::Base` only: https://github.com/rails/rails/pull/50396
but for this to work we must first refactor any Rails code that rely on it.
which respects reject_if and is in nested_attributes order.
When in default index_errors:true mode,
fix#24390 and return index based on full association order.
This commit adds a deprecation warning for the `query_constraints:`
association option. This option will change behavior in the future versions
of Rails and applications are encouraged to switch to `foreign_key:` to preserve the
current behavior.
We're already conditioning `reflection_fk` based on whether it's an
`Array` or not, so no need to wrap it in this `Array()` call since in
this block it is sure to be an `Array`.
Ref.: d7980c6b10
Using the same benchmark as in https://github.com/rails/rails/pull/51726
`replace_keys` always allocate a multiple arrays to support composite
primary keys, even though most primary keys likely aren't composite.
And even when they are, we can avoid needless allocations by not using
`Array#zip`.
This reduce allocations by 18% (8k) on that benchmark.
Before:
```
Total allocated: 4.88 MB (44495 objects)
Total retained: 4.16 MB (32043 objects)
allocated memory by file
-----------------------------------
...
320.00 kB activerecord/lib/active_record/associations/belongs_to_association.rb
allocated objects by file
-----------------------------------
...
8000 activerecord/lib/active_record/associations/belongs_to_association.rb
```
After:
```
Total allocated: 4.56 MB (36495 objects)
Total retained: 4.16 MB (32041 objects)
```
NB: `belongs_to_association` doesn't show up in top files anymore
Last big refactor was in https://github.com/rails/rails/pull/37614.
Somewhat extracted from https://github.com/rails/rails/pull/51744.
The concern about columns with the same name didn't make much sense
to me because in both code paths, the last one wins, so we can simplify
the whole methods.
Additionally by implementing `columns_index`, we have a decent template
always available.
Using a simple benchmark such as:
```ruby
Post.transaction do
100.times do
post = Post.create!(author_id: 42, title: "A" * 50, body: "a" * 400, tags: "blah blah blah", published_at: Time.now, comments_count: 20)
20.times do
post.comments.create!(author_id: 42, body: "a" * 120, tags: "blah blah blah", published_at: Time.now)
end
end
end
posts = Post.includes(:comments).to_a
```
This allocate `43,077` objects, and out of these `2,200` are caused by association
names being stored as strings internally:
```
Allocated String Report
-----------------------------------
80.00 kB 2000 "post"
2000 activerecord/lib/active_record/reflection.rb:123
8.00 kB 200 "comments"
200 activerecord/lib/active_record/reflection.rb:123
```
This is because many API accept either symbol or string, and blindly
call `to_s` on it. We could avoid this with sprinkling the code with
`Symbol == association ? association.name : association.to_s`, but it's
ugly.
This issue may be entirely solved in a future Ruby version, but
it will take years: https://bugs.ruby-lang.org/issues/20350
By using symbols, we both save allocations, and marginally speed up
lookups and comparisons, reducing this particular benchmark allocations
by 5%.
It's a bit unclear why these were ever made strings. Historically
symbols were immortal and using them for user supplied data could lead
to DOS vulnerability, so this may have been why, but it's not longer
a concern since Ruby 2.2.
I'm looking at reducing the allocations and memory footprint
of Active Record models, and based on a small benchmark I saw
a lot of numeric strings being created from `stale_state`.
I tracked this cast all the way down to 1c07b84df9
but unfortunately the commit message doesn't explain why it was added.
I can't think of a reason why this would be needed.
The benchmark is essentially just: `Post.includes(:comments).to_a` with
`100` posts and `20` comments each.
```
Total allocated: 4.69 MB (45077 objects)
Total retained: 3.84 MB (29623 objects)
retained objects by location
-----------------------------------
...
2000 activerecord/lib/active_record/associations/belongs_to_association.rb:152
retained memory by location
-----------------------------------
...
80.00 kB activerecord/lib/active_record/associations/belongs_to_association.rb:152
```
NB: This break the final assertion of the Rails 6.1 Marshal backward compatibility
test, but I think it's an acceptable tradeoff.