| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|\ \ \
| | | |
| | | | |
Change `gsub` to `tr` where possible
|
| | |/
| |/| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
For detailed testing of behavior see:
https://gist.github.com/eileencodes/5b0a2fe011dcff6203fe
This shows destroy_all always destroys records and fires callbacks.
It will never use nullify or delete_all
delete_all's behavior varies greatly based on `hm` vs `hm:t` and deletion
strategy.
|
|\ \ \
| |/ /
|/| |
| | |
| | | |
justinweiss/update_validation_context_documentation
Docs: Add a note on custom validation contexts. [ci skip]
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The documentation on `:on` for validations was inconsistent, and most
only referenced the `:create` and `:update` contexts. I fixed those to
be consistent with the documentation on `AM::Validations.validates`,
which seemed to have the best docs.
[ci skip]
|
| | | |
|
|\ \ \
| | | |
| | | |
| | | |
| | | | |
phiggins/remove-dynamic-send-on-built-in-callbacks
Reduce allocations when running AR callbacks.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Inspired by @tenderlove's work in
c363fff29f060e6a2effe1e4bb2c4dd4cd805d6e, this reduces the number of
strings allocated when running callbacks for ActiveRecord instances. I
measured that using this script:
```
require 'objspace'
require 'active_record'
require 'allocation_tracer'
ActiveRecord::Base.establish_connection adapter: "sqlite3",
database: ":memory:"
ActiveRecord::Base.connection.instance_eval do
create_table(:articles) { |t| t.string :name }
end
class Article < ActiveRecord::Base; end
a = Article.create name: "foo"
a = Article.find a.id
N = 10
result = ObjectSpace::AllocationTracer.trace do
N.times { Article.find a.id }
end
result.sort.each do |k,v|
p k => v
end
puts "total: #{result.values.map(&:first).inject(:+)}"
```
When I run this against master and this branch I get this output:
```
pete@balloon:~/projects/rails/activerecord$ git checkout master
M Gemfile
Switched to branch 'master'
pete@balloon:~/projects/rails/activerecord$ bundle exec ruby benchmark_allocation_with_callback_send.rb > allocations_before
pete@balloon:~/projects/rails/activerecord$ git checkout remove-dynamic-send-on-built-in-callbacks
M Gemfile
Switched to branch 'remove-dynamic-send-on-built-in-callbacks'
pete@balloon:~/projects/rails/activerecord$ bundle exec ruby benchmark_allocation_with_callback_send.rb > allocations_after
pete@balloon:~/projects/rails/activerecord$ diff allocations_before allocations_after
39d38
<
{["/home/pete/projects/rails/activesupport/lib/active_support/callbacks.rb",
81]=>[40, 0, 0, 0, 0, 0]}
42c41
< total: 630
---
> total: 590
```
In addition to this, there are two micro-optimizations present:
* Using `block.call if block` vs `yield if block_given?` when the block was being captured already.
```
pete@balloon:~/projects$ cat benchmark_block_call_vs_yield.rb
require 'benchmark/ips'
def block_capture_with_yield &block
yield if block_given?
end
def block_capture_with_call &block
block.call if block
end
def no_block_capture
yield if block_given?
end
Benchmark.ips do |b|
b.report("block_capture_with_yield") { block_capture_with_yield }
b.report("block_capture_with_call") { block_capture_with_call }
b.report("no_block_capture") { no_block_capture }
end
pete@balloon:~/projects$ ruby benchmark_block_call_vs_yield.rb
Calculating -------------------------------------
block_capture_with_yield
124979 i/100ms
block_capture_with_call
138340 i/100ms
no_block_capture 136827 i/100ms
-------------------------------------------------
block_capture_with_yield
5703108.9 (±2.4%) i/s - 28495212 in 4.999368s
block_capture_with_call
6840730.5 (±3.6%) i/s - 34169980 in 5.002649s
no_block_capture 5821141.4 (±2.8%) i/s - 29144151 in 5.010580s
```
* Defining and calling methods instead of using send.
```
pete@balloon:~/projects$ cat benchmark_method_call_vs_send.rb
require 'benchmark/ips'
class Foo
def tacos
nil
end
end
my_foo = Foo.new
Benchmark.ips do |b|
b.report('send') { my_foo.send('tacos') }
b.report('call') { my_foo.tacos }
end
pete@balloon:~/projects$ ruby benchmark_method_call_vs_send.rb
Calculating -------------------------------------
send 97736 i/100ms
call 151142 i/100ms
-------------------------------------------------
send 2683730.3 (±2.8%) i/s - 13487568 in 5.029763s
call 8005963.9 (±2.7%) i/s - 40052630 in 5.006604s
```
The result of this is making typical ActiveRecord operations slightly faster:
https://gist.github.com/phiggins/e46e51dcc7edb45b5f98
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Hash#keys.each allocates an array of keys; Hash#each_key iterates through the
keys without allocating a new array. This is the reason why Hash#each_key
exists.
|
|/ / /
| | |
| | |
| | | |
@column_names_with_alias, @dynamic_methods_hash, @time_zone_column_names, and @cached_time_zone
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Benchmark:
```ruby
require 'objspace'
require 'active_record'
ActiveRecord::Base.establish_connection adapter: "sqlite3",
database: ":memory:"
ActiveRecord::Base.connection.instance_eval do
create_table(:articles) { |t| t.string :name }
end
class Article < ActiveRecord::Base; end
a = Article.create name: "foo"
a = Article.find a.id
N = 10
ObjectSpace::AllocationTracer.trace do
N.times { Article.find a.id }
end
ObjectSpace::AllocationTracer.allocated_count_table
table.sort_by { |_,x| x }.each do |k,v|
p k => (v / N)
end
```
|
| | | |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Honoring an overidden `rack.test` allows testing closed connection between
multiple requests. This is useful if you're working on database resiliency, to
ensure the connection is in the expected state from one request to another on
the same worker.
|
| |/
|/|
| |
| |
| |
| | |
it doesn't work on SQLite3 since it doesn't support truncate, but that's
OK. If you call truncate on the connection, you're now bound to that
database (same as if you use hstore or any other db specific feature).
|
| |
| |
| |
| |
| |
| |
| | |
Previously the documentation stated that `primary_key` should be the name of
a *method* that returns the primary key used for the association. This is
incorrect. This changes the documentation to say that the value must be the
name of a column.
|
| |
| |
| |
| | |
:foreign_key option that's a symbol
|
| |
| |
| |
| |
| | |
The hash is now string-keyed, and [_]reflect_on_association calls `to_s` on the
argument anyway.
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
For now, we will just skip the cache when a non-column key is used in the hash.
If the future, we can probably move some of the logic in PredicateBuilder.expand
up the chain to make caching possible for association queries.
Closes #16903
Fixes #16884
|
| |
| |
| |
| |
| |
| | |
This is pretty lame though, so feel free to send a PR with a better fix! ;)
cc @zev @tenderlove
|
|\ \
| | |
| | | |
Update RecordNotFound exception cases to include a message with the
|
| | |
| | |
| | |
| | | |
Model that the Record was not found in.
|
| | |
| | |
| | |
| | |
| | |
| | | |
- Added a note about some features which are not dependent on
auto-generated ID's.
- [ci skip]
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
While investigating #16951 I found that another library's monkey-patching of
`Enumerable` was causing the test migrations helper to break when trying to
build the `CREATE DATABASE` statement. The prior approach used `#sum` to build
the string from the options hash.
As the code that combines the options to build the database statement is not
user-facing, using `#inject` here instead will remove the only place where the
database creation/migration code is dependent on ActiveSupport's monkey-patching
of `Enumerable`.
|
| | | |
|
|\ \ \
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Don't autosave unchanged has_one through records
Conflicts:
activerecord/CHANGELOG.md
|
| | | | |
|
|\ \ \ \
| | | | |
| | | | | |
Allow YAML serialization when using TZ aware attributes
|
| | | | | |
|
|\ \ \ \ \
| |/ / / /
|/| | | |
| | | | |
| | | | | |
kongregate/fix-activerecord-deprecated_finders-find-symbol
ActiveRecord deprecated finders are broken in 4.2
|
| |/ / /
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Maintain compatibility for:
* ActiveRecord::Base#find(:all)
* ActiveRecord::Base#find(:first)
* ActiveRecord::Base#find(:last)
|
| | | | |
|
|/ / /
| | |
| | |
| | |
| | |
| | | |
Closes #16907.
[Matthew Draper & Yves Senn]
|
|\ \ \
| | | |
| | | |
| | | | |
Data corruption risk: Roll back open transactions when the running thread is killed.
|
| | | | |
|
|\ \ \ \
| | | | |
| | | | | |
Improved the error messaging for the DangerousAttributeError exception
|
| | | | |
| | | | |
| | | | |
| | | | | |
that the conflict could be because of a conflicting attribute.
|
|/ / / /
| | | |
| | | |
| | | |
| | | |
| | | | |
[Matthew Draper & Yves Senn]
Closes #16860. (pull request to discuss the implementation)
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Allows :limit defaults to be changed without pulling the rug out from
under old migrations that omitted :limit because it matched the default
at the time.
|
| | | | |
|
| | | | |
|
|\ \ \ \
| | | | |
| | | | | |
Updating Associations::Preloader docs
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Much of the previous documentation introduced features new in 2011. This
commit refreshes it to provide clearer code examples and spends more
time describing the normal case (preloaded associations) and less time
describing the fallback.
[ci skip]
|
|\ \ \ \ \
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
SQLite3Adapter now checks for views in table_exists? fixes: 14041
Conflicts:
activerecord/CHANGELOG.md
|
| | | | | | |
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
`AbstractAdapter#supports_views?` defaults to `false` so we have to turn it on
in adapter subclasses. Currently the flag only controls test execution.
/cc @yahonda
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Closes #16684.
This is achieved by always generating `GeneratedAssociationMethods` when
`ActiveRecord::Base` is subclassed. When some of the included modules
of `ActiveRecord::Base` were reordered this behavior was broken as
`Core#initialize_generated_modules` was no longer called. Meaning that
the module was generated on first access.
|
|\ \ \ \ \ \
| | | | | | |
| | | | | | | |
Fix query with nested array in Active Record
|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
`User.where(id: [[1,2],3])` was equal to `User.where(id:[1, 2, 3])`
in Rails 4.1.x but because of some refactoring in Arel this stopped
working in 4.2.0. This fixes it in Rails.
[Dan Olson & Cristian Bica]
|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
exclusively
|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
* Add private method primary_key_for, which more clearly shows that the
expected return value is nil when a primary key is not found.
|