| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
| |
Some methods were added to public API in
5b14129d8d4ad302b4e11df6bd5c7891b75f393c and they should be not part of
the public API.
|
| |
|
|
|
|
|
|
| |
Mainly around `nil`
[ci skip]
|
|
|
|
|
|
| |
All indentation was normalized by rubocop auto-correct at 80e66cc4d90bf8c15d1a5f6e3152e90147f00772.
But comments was still kept absolute position. This commit aligns
comments with method definitions for consistency.
|
|\
| |
| | |
Check if the logger is not nil before using it
|
| | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
A few have been left for aesthetic reasons, but have made a pass
and removed most of them.
Note that if the method `foo` returns an array, `foo << 1`
is a regular push, nothing to do with assignments, so
no self required.
|
| | |
|
|/
|
|
|
| |
The current code base is not uniform. After some discussion,
we have chosen to go with double quotes by default.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This reverts commit f6db31ec16e42ee7713029f7120f0b011d1ddc6c.
Reason:
Scope names can very easily conflict, particularly when sharing Concerns
within the team, or using multiple gems that extend AR models.
It is true that Ruby has the ability to detect this with the -w option, but the
reality is that we are depending on too many gems that do not care about Ruby
warnings, therefore it might not be a realistic solution to turn this switch on
in our real-world apps.
|
|\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
* 5-0-beta-sec:
bumping version
fix version update task to deal with .beta1.1
Eliminate instance level writers for class accessors
allow :file to be outside rails root, but anything else must be inside the rails view directory
Don't short-circuit reject_if proc
stop caching mime types globally
use secure string comparisons for basic auth username / password
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Instance level writers can have an impact on how the Active Model /
Record objects are saved. Specifically, they can be used to bypass
validations. This is a problem if mass assignment protection is
disabled and specific attributes are passed to the constructor.
CVE-2016-0753
|
|/
|
|
|
|
|
|
|
|
|
|
|
| |
Given a default_scope on a parent of the current class, where that
parent is not the base class, the parent's STI condition would become
attached to the evaluated default scope, and then override the child's
own STI condition.
Instead, we can treat the STI condition as though it is a default scope,
and skip it in this situation: the scope will be merged into the base
relation, which already contains the correct STI condition.
Fixes #22426.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The focus of this change is to make the API more accessible.
References to method and classes should be linked to make it easy to
navigate around.
This patch makes exzessiv use of `rdoc-ref:` to provide more readable
docs. This makes it possible to document `ActiveRecord::Base#save` even
though the method is within a separate module
`ActiveRecord::Persistence`. The goal here is to bring the API closer to
the actual code that you would write.
This commit only deals with Active Record. The other gems will be
updated accordingly but in different commits. The pass through Active
Record is not completely finished yet. A follow up commit will change
the spots I haven't yet had the time to update.
/cc @fxn
|
|
|
|
|
|
|
|
|
|
|
| |
Adds a paragraph to the documentation of the `ActiveRecord::Scoping::Named.scope` method,
explaining that the method is intended to return an ActiveRecord::Relation object to be
composable with other scopes.
In the case that in the case that `nil` or `false` are returned, the method returns
an `all` relation instead.
This unexpected behaviour is mentioned in #19249 #14256 #21465 and #21882 and wasn't
documented at all. This commit adds this documentation.
|
|\
| |
| | |
PERF: Scope performance.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Benchmark Script:
```
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
raise e
end
gemfile(true) do
source 'https://rubygems.org'
# gem 'rails', github: 'rails/rails', ref: 'f1f0a3f8d99aef8aacfa81ceac3880dcac03ca06'
gem 'rails', path: '~/rails'
gem 'arel', github: 'rails/arel', branch: 'master'
gem 'rack', github: 'rack/rack', branch: 'master'
gem 'sass'
gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
gem 'sprockets', github: 'rails/sprockets', branch: 'master'
gem 'pg'
gem 'benchmark-ips'
end
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench')
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string :name, :email
t.timestamps null: false
end
end
class User < ActiveRecord::Base; end
attributes = {
name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
email: "foobar@email.com",
}
1000.times { User.create!(attributes) }
Benchmark.ips(5, 3) do |x|
x.report('where with hash') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
x.report('where with string') { User.where("users.name = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
x.compare!
end
key =
if RUBY_VERSION < '2.2'
:total_allocated_object
else
:total_allocated_objects
end
before = GC.stat[key]
User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
after = GC.stat[key]
puts "Total Allocated Object: #{after - before}"
```
Stackprof output truncated.
```
TOTAL (pct) SAMPLES (pct) FRAME
52 (10.6%) 10 (2.0%) ActiveRecord::Scoping::Default::ClassMethods#build_default_scope
```
Before:
```
Calculating -------------------------------------
where with hash 2.789k i/100ms
where with string 4.407k i/100ms
-------------------------------------------------
where with hash 29.170k (± 1.9%) i/s - 147.817k
where with string 46.954k (± 2.7%) i/s - 237.978k
Comparison:
where with string: 46954.3 i/s
where with hash: 29169.9 i/s - 1.61x slower
Total Allocated Object: 85
Calculating -------------------------------------
all 16.773k i/100ms
-------------------------------------------------
all 186.102k (± 3.6%) i/s - 939.288k
```
After:
```
Calculating -------------------------------------
where with hash 3.014k i/100ms
where with string 4.623k i/100ms
-------------------------------------------------
where with hash 31.524k (± 1.3%) i/s - 159.742k
where with string 49.948k (± 2.3%) i/s - 249.642k
Comparison:
where with string: 49948.3 i/s
where with hash: 31524.3 i/s - 1.58x slower
Total Allocated Object: 84
Calculating -------------------------------------
all 20.139k i/100ms
-------------------------------------------------
all 227.860k (± 2.5%) i/s - 1.148M
```
|
|/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Benchmark script used:
```
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
raise e
end
gemfile(true) do
source 'https://rubygems.org'
gem 'rails', path: '~/rails' # master against ref "f1f0a3f8d99aef8aacfa81ceac3880dcac03ca06"
gem 'arel', github: 'rails/arel', branch: 'master'
gem 'rack', github: 'rack/rack', branch: 'master'
gem 'sass'
gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
gem 'sprockets', github: 'rails/sprockets', branch: 'master'
gem 'pg'
gem 'benchmark-ips'
end
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench')
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string :name, :email
t.timestamps null: false
end
end
class User < ActiveRecord::Base; end
attributes = {
name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
email: "foobar@email.com",
}
1000.times { User.create!(attributes) }
Benchmark.ips(5, 3) do |x|
x.report('all') { User.all }
end
key =
if RUBY_VERSION < '2.2'
:total_allocated_object
else
:total_allocated_objects
end
before = GC.stat[key]
User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
after = GC.stat[key]
puts "Total Allocated Object: #{after - before}"
```
Before:
```
Calculating -------------------------------------
all 17.569k i/100ms
-------------------------------------------------
all 190.854k (± 3.3%) i/s - 966.295k
Total Allocated Object: 85
```
After:
```
Calculating -------------------------------------
all 22.237k i/100ms
-------------------------------------------------
all 262.715k (± 5.5%) i/s - 1.312M
Total Allocated Object: 80
```
|
|
|
|
|
|
|
|
|
|
| |
class
Fixes #19528
fix for mysql2 test
better test
|
|
|
|
|
|
| |
- Eager loading was not working for the default_scope (class method)
for 'find' & 'find_by' methods.
- Fixed these by adding a new check 'respond_to?(:default_scope)'.
|
|
|
|
|
|
|
|
|
|
|
| |
Instead use .scope_attributes? consistently in ActiveRecord to check whether
there are attributes currently associated with the scope.
Move the implementation of .scope_attributes? and .scope_attributes to
ActiveRecord::Scoping because they don't particularly have to do specifically
with Named scopes and their only dependency, in the case of
.scope_attributes?, and only caller, in the case of .scope_attributes is
contained in Scoping.
|
|
|
|
|
|
|
|
|
|
|
|
| |
It looks like the only reason `current_scope` was thread local on
`base_class` instead of `self` is to ensure that when we call a named
scope created with a proc on the parent class, it correctly uses the
default scope of the subclass. The reason this wasn't happening was
because the proc captured `self` as the parent class, and we're not
actually defining a real method. Using `instance_exec` fixes the
problem.
Fixes #18806
|
|
|
|
|
|
|
|
| |
Relation#merge checks if the argument is an array and the only possible
returns of build_default_scope is nil or a Relation.
Doing this we can raise an ArgumentError when Relation#merge receive a
nil value.
|
| |
|
|\
| |
| |
| | |
Raises ArgumentError when try to define a scope without a callable
|
|/
|
|
|
|
| |
This changes the actual exception `NoMethodError: undefined method `call'
for #<ActiveRecord::Relation []>` to a `ArgumentError` when try to define
a scope without a callable.
|
|
|
|
|
|
|
|
|
|
|
|
| |
This reverts commit 9a1abedcdeecd9464668695d4f9c1d55a2fd9332, reversing
changes made to c72d6c91a7c0c2dc81cc857a1d6db496e84e0065.
Conflicts:
activerecord/CHANGELOG.md
activerecord/test/models/comment.rb
This change break integration with activerecord-deprecated_finders so
I'm reverting until we find a way to make it work with this gem.
|
|\
| |
| |
| |
| |
| |
| | |
Fixes Issue #13466.
Conflicts:
activerecord/CHANGELOG.md
|
| |
| |
| |
| |
| |
| | |
Changed the call to a scope block to be evaluated with instance_eval.
The result is that ScopeRegistry can use the actual class instead of base_class when
caching scopes so queries made by classes with a common ancestor won't leak scopes.
|
|\ \
| |/
|/| |
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
|
| |
| |
| |
| | |
Thank you @bquorning
|
|/
|
|
|
| |
[ci-skip]
Closes rails/rails#14294
|
|
|
|
|
|
|
|
|
|
| |
Similar to dangerous attribute methods, a scope name conflict is
dangerous if it conflicts with an existing class method defined within
`ActiveRecord::Base` but not its ancestors.
See also #13389.
*Godfrey Chan*, *Philippe Creux*
|
|
|
|
|
| |
We are checking this when defining the default scope and raising an
ArgumentError
|
|
|
|
| |
The deprecation message was removed on 50cbc03d18c5984347965a94027879623fc44cce but the code was not.
|
|
|
|
| |
Removed tests from deprecated code.
|
|
|
|
| |
Calling default_scope without a proc will now raise `ArgumentError`.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The previous implementation was necessary in order to support stuff
like:
class Post < ActiveRecord::Base
default_scope where(published: true)
scope :ordered, order("created_at")
end
If we didn't evaluate the default scope at the last possible moment
before sending the SQL to the database, it would become impossible to
do:
Post.unscoped.ordered
This is because the default scope would already be bound up in the
"ordered" scope, and therefore wouldn't be removed by the
"Post.unscoped" part.
In 4.0, we have deprecated all "eager" forms of scopes. So now you must
write:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
scope :ordered, -> { order("created_at") }
end
This prevents the default scope getting bound up inside the "ordered"
scope, which means we can now have a simpler/better/more natural
implementation of default scoping.
A knock on effect is that some things that didn't work properly now do.
For example it was previously impossible to use #except to remove a part
of the default scope, since the default scope was evaluated after the
call to #except.
|
|
|
|
| |
current ScopeRegister object.
|
|
|
|
|
| |
current_scope and ignore_default_scope locals are brought together under
a registry object.
|
|
|
|
| |
See #10107.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
See #9869 and #9929.
The problem arises from the following example:
class Project < ActiveRecord::Base
scope :completed, -> { where completed: true }
end
class MajorProject < Project
end
When calling:
MajorProject.where(tasks_count: 10).completed
This expands to:
MajorProject.where(tasks_count: 10).scoping {
MajorProject.completed
}
However the lambda for the `completed` scope is defined on Project. This
means that when it is called, `self` is Project rather than
MajorProject. So it expands to:
MajorProject.where(tasks_count: 10).scoping {
Project.where(completed: true)
}
Since the scoping was applied on MajorProject, and not Project, this
fails to apply the tasks_count condition.
The solution is to make scoping apply across STI classes. I am slightly
concerned about the possible side-effects of this, but no tests fail and
it seems ok. I guess we'll see.
|
|
|
|
|
| |
Update comment to reflect that unscoped works with named scope
even when named scope is using without block form
|
|
|
|
|
|
|
| |
Introduced in f1082b8588a9144eedb34d511f0074031f692d98.
Full changelog in 9f007d7fe5f90257c71baa2c4e7c76fb44512986.
[ci skip]
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently Post.active.inactive will result in Post.inactive since
the last where clause wins when scopes are merged.
This pull request will merge all scopes ( barring defaul scope)
using AND.
The default scope will be overridden if another scope acts on the
same where clause.
closes #7365
|
| |
|