| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I'm not sure what's the use case for this, but apparently it broke some apps.
Since it was not the intended result from #16210 I fixed it to not raise an
exception anymore. However, I didn't add documentation for it because I don't
know if this should be officially supported without knowing how it's meant to
be used.
In general, validations should be side-effect-free (other than adding to the
error message to `@errors`). Order-dependent validations seems like a bad idea.
Fixes #18002
|
|
|
|
| |
This will avoid naming clash with user defined methods
|
|\
| |
| |
| |
| | |
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]
|
| | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
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
|
| | |
|
| |
| |
| |
| |
| | |
- Improve the error message by suggesting that the user may have
intended to call validates instead of validate method.
|
|\ \
| |/
|/|
| | |
Use #model_name on instances instead of classes
|
| |
| |
| |
| |
| |
| | |
This allows rails code to be more confdent when asking for a model name, instead of having to ask for the class.
Rails core discussion here: https://groups.google.com/forum/#!topic/rubyonrails-core/ThSaXw9y1F8
|
| | |
|
|/
|
|
|
|
|
|
|
|
|
| |
This change prevents a certain class of user error which results when
mistakenly using the `validate` class method instead of the `validates`
class method.
Only apply when all arguments are symbols, because some validations use
the `validate` method and pass in additional options, namely the
`LenghValidator` via the `ActiveMode::Validations::validates_with`
method.
|
|
|
|
|
|
|
|
| |
It's unintuitive to call '#valid?' when you want to run validations but
don't care about the return value.
The alias in ActiveRecord isn't strictly necessary (the ActiveModel
alias is still in effect), but it clarifies.
|
| |
|
|
|
|
|
|
| |
Example:
validates_presence_of :name, on: [:update, :custom_validation_context]
|
|
|
|
|
|
| |
& Xavier Noria]
Closes #11247.
|
|
|
|
| |
links in rdoc [ci skip]
|
| |
|
| |
|
|
|
|
|
| |
I also attempted to fix other styleguide violations such as
{ a: :b } over {a: :b} and foo(b: 'bar') over foo( b: 'bar' ).
|
|
|
|
| |
rest of the code the wat the includes are done
|
|
|
|
|
|
| |
it only cleared the validations that created :validate callbacks. This
didn't include the validates created by validates_with, so I've added a
method to clear all validations.
|
| |
|
| |
|
|\
| |
| |
| |
| |
| | |
Conflicts:
activesupport/lib/active_support/core_ext/hash/slice.rb
guides/source/active_support_core_extensions.md
|
| | |
|
| | |
|
|/ |
|
|
|
|
| |
Thanks to @jeremy to teach me this one.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This reverts commit 4e9f53f9736544f070e75e516c71137b7eb49a7a, reversing
changes made to 6b802cdb4f5b84e1bf49aaeb0e994b3be6028af9.
Revert "Don't use tap in this case."
This reverts commit 454d820bf0a18fe1db4c55b0145197d70fef1f82.
Reason: Is not a good idea to add options to this method since we can do
the same thing using method composition.
Person.validators_on(:name).select { |v| v.kind == :presence }
Also it avoids to change the method again to add more options.
|
|
|
|
|
| |
The use of tap in this case is very confusing since we are mutating the
return value inside the block
|
|
|
|
|
| |
This will filter out the validators on a particular attribute based on
its kind.
|
|\
| |
| |
| |
| |
| | |
Conflicts:
activemodel/lib/active_model/secure_password.rb
activerecord/lib/active_record/associations/collection_proxy.rb
|
| | |
|
|/ |
|
|
|
|
|
|
|
|
| |
There's no need to create two extra hashes with options.merge(another_hash),
with the goal of setting only one value, so lets just set it.
Also refactor validates_each to use _merge_attributes, like other
validates_* helpers do.
|
|\ |
|
| | |
|
| | |
|
|/
|
|
|
| |
Get rid of ActiveModel::Configuration, make better use of
ActiveSupport::Concern + class_attribute, etc.
|
| |
|
|
|
|
| |
Fixes #5953
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem: We need to be able to specify configuration in a way that
can be inherited to models that include ActiveRecord::Model. So it is
no longer sufficient to put 'top level' config on ActiveRecord::Base,
but we do want configuration specified on ActiveRecord::Base and
descendants to continue to work.
So we need something like class_attribute that can be defined on a
module but that is inherited when ActiveRecord::Model is included.
The solution: added ActiveModel::Configuration module which provides a
config_attribute macro. It's a bit specific hence I am not putting this
in Active Support or making it a 'public API' at present.
|
| |
|