| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
| | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
```
# before
DEPRECATION WARNING: Time columns will become time zone aware in Rails 5.1. This
still causes `String`s to be parsed as if they were in `Time.zone`,
and `Time`s to be converted to `Time.zone`.
To keep the old behavior, you must add the following to your initializer:
config.active_record.time_zone_aware_types = [:datetime]
To silence this deprecation warning, add the following:
config.active_record.time_zone_aware_types << :time
```
```
# after
DEPRECATION WARNING: Time columns will become time zone aware in Rails 5.1. This
still causes `String`s to be parsed as if they were in `Time.zone`,
and `Time`s to be converted to `Time.zone`.
To keep the old behavior, you must add the following to your initializer:
config.active_record.time_zone_aware_types = [:datetime]
To silence this deprecation warning, add the following:
config.active_record.time_zone_aware_types << :time
```
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This reverts commit 6d5b1fdf55611de2a1071c37544933bb588ae88e.
`eager_load` and `references` can include hashes, which won't match up
with `references`
A test case has been added to demonstrate the problem
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This was changed in 421c81b, as `exists?` blows up if you are eager
loading a polymorphic association, as it'll try to construct a join to
that table. The previous change decided to execute a `count` instead,
which wouldn't join.
Of course, the only time we actually need to perform a join on the eager
loaded values (which would perform a left outer join) is if they're
being referenced in the where clause. This doesn't affect inner joins.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
We currently generate an unbounded number of prepared statements when
`limit` or `offset` are called with a dynamic argument. This changes
`LIMIT` and `OFFSET` to use bind params, eliminating the problem.
`Type::Value#hash` needed to be implemented, as it turns out we busted
the query cache if the type object used wasn't exactly the same object.
This drops support for passing an `Arel::Nodes::SqlLiteral` to `limit`.
Doing this relied on AR internals, and was never officially supported
usage.
Fixes #22250.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Some backends allow `LIMIT 1,2` as a shorthand for `LIMIT 1 OFFSET 2`.
Supporting this in Active Record massively complicates using bind
parameters for limit and offset, and it's trivially easy to build an
invalid SQL query by also calling `offset` on the same `Relation`.
This is a niche syntax that is only supported by a few adapters, and can
be trivially worked around by calling offset explicitly.
|
| |
| |
| |
| |
| | |
It appears that I missed this one when I delegated all the non-mutation
array methods that were not on Enumerable
|
| |
| |
| |
| | |
[ci skip]
|
|\ \
| | |
| | | |
Update and fix forbidden attributes test issues caused by AC::Parameters change
|
| | |
| | |
| | |
| | | |
Add AC::Parameters tests for WhereChain#not
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
As was pointed out by #17128, our blacklist of mutation methods was
non-exhaustive (and would need to be kept up to date with each new
version of Ruby). Now that `Relation` includes `Enumerable`, the number
of methods that we actually need to delegate are pretty small. As such,
we can change to explicitly delegating the few non-mutation related
methods that `Array` has which aren't on `Enumerable`
|
| | |
| | |
| | |
| | |
| | |
| | | |
In b71e08f we started raising when nil or false was passed to merge to
fix #12264, however we should also do this for truthy values that are
invalid like true.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
From Ruby ( 2.3.0dev trunk 52520), `Hash#to_proc` is defined
(https://github.com/ruby/ruby/commit/fbe967ec02cb65a7efa3fb8f3d747cf6f620dde1),
and many tests have been failed with
`ArgumentError: wrong number of arguments (given 0, expected 1)`.
Because we call `Hash#to_proc` with no args in `#merge!`.
This commit changes order of conditionals to not call `Hash#to_proc`.
|
|/ /
| |
| |
| |
| |
| |
| | |
[ci skip]
There was a `ActiveRecord::Relation::RecordFetchWarning::ActiveSupport`
artifact caused by subscribing to AS notifications.
|
| |
| |
| |
| | |
This commit follows up of 6a6dbb4c51fb0c58ba1a810eaa552774167b758a.
|
| | |
|
|\ \
| | |
| | |
| | | |
added ActiveRecord::Relation#outer_joins
|
| | |
| | |
| | |
| | |
| | |
| | | |
Example:
User.left_outer_joins(:posts)
=> SELECT "users".* FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"
|
|\ \ \
| | | |
| | | |
| | | | |
Support SQL sanitization in AR::QueryMethods#order
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Add support for sanitizing arrays in SQL ORDER clauses.
This is useful when using MySQL `ORDER BY FIELD()` to return records in
a predetermined way.
```ruby
Tag.order(['field(id, ?', [1,3,2]].to_sql
# => SELECT "tags".* FROM "tags" ORDER BY field(id, 1,3,2)
```
Prior to this, developers must be careful to sanitize `#order` arguments
themselves.
|
| | | | |
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
* When tried to use `Company#accounts` test/models/company.rb I got:
```
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column:
accounts.company_id: SELECT COUNT(*) AS count_all, "companies"."firm_id"
AS companies_firm_id FROM "companies" INNER JOIN "accounts" ON
"accounts"."company_id" = "companies"."id" GROUP BY "companies"."firm_id"
```
* The refactor on Calculations class was just to simplify the code
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Closes #21922
Let `Book(id, author_id)`, `Photo(id, book_id, author_id)` and `Author(id)`
Running `Book.group(:author_id).joins(:photos).count` will produce:
* Rails 4.2 - conflicts `author_id` in both projection and group by:
```sql
SELECT COUNT(*) AS count_all, author_id AS author_id
FROM "books" INNER JOIN "photos" ON "photos"."book_id" = "books"."id"
GROUP BY author_id
```
* Master (9d02a25) - conflicts `author_id` only in projection:
```sql
SELECT COUNT(*) AS count_all, author_id AS author_id
FROM "books" INNER JOIN "photos" ON "photos"."book_id" = "books"."id"
GROUP BY "books"."author_id"
```
* With this fix:
```sql
SELECT COUNT(*) AS count_all, "books"."author_id" AS books_author_id
FROM "books" INNER JOIN "photos" ON "photos"."book_id" = "books"."id"
GROUP BY "books"."author_id"
```
|
|\ \ \ \
| | | | |
| | | | | |
Allow select using Arel and perform a count
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
It allows a query like `User.select(:name).count` to be written
using Arel as `User.select(User.arel_table[:name]).count`.
It exposes the calculations API to accept Arel nodes:
`User.count(User.arel_table[:name])`, `User.sum(User.arel_table[:id])`,
`Account.average(Account.arel_table[:credit_limit])`,
`Account.maximum(Account.arel_table[:credit_limit])` and
`Account.minimum(Account.arel_table[:credit_limit])`.
|
| | | | |
| | | | |
| | | | |
| | | | | |
Column names inserted via `group` have to be qualified with table name.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This commit follow up of 4d8f62d.
The difference from 4d8f62d are below:
* Change `WhereClauseFactory` to accept `Arel::Nodes::Node`
* Change test cases of `relation_test.rb`
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This reverts commit 4d8f62dcfa0a5157b3facbd71f75fc6639636347.
Reason: This broke the build. Please recommit again when it is green.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
`WhereClauseFactory` handles all other branches based on argument types,
so the code fits more naturally here, and it's just where the
responsibility belongs.
|
| | | | |
| | | | |
| | | | |
| | | | | |
[#20473]
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
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
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
The rdoc parser seems to trip on the `private def` construct.
Public methods following a method defined with `private def` are not
visible inside the module docs but are appended to the top-most module.
For example the method `ActiveRecord::QueryMethods#distinct` was listed
under `ActiveRecord#distinct`.
/cc @sgrif
|
| | | | |
| | | | |
| | | | |
| | | | | |
[ci skip]
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Also unify the format of code example output. Only use `# =>` if the
actual return value is described. Otherwise simply use `#`.
Conflicts:
activerecord/lib/active_record/relation/query_methods.rb
|
| | | | | |
|
| | | | | |
|
| | | | |
| | | | |
| | | | |
| | | | | |
`require 'active_support/core_ext/string/filters'` was added in b3bfa36. However, it is no longer needed from 3ae981814.
|
| | | | | |
|
|\ \ \ \ \
| | | | | |
| | | | | | |
`column_alias_for` method is no more supporting *keys [ci skip]
|
| | | | | | |
|
|/ / / / /
| | | | |
| | | | |
| | | | | |
ClassMethod, Since commit https://github.com/rails/rails/commit/a3936bbe21f4bff8247f890cacfd0fc882921003 [ci skip]
|
| | | | | |
|
| | | | | |
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This removes the following warning.
```
activerecord/lib/active_record/relation/calculations.rb:74: warning: `&' interpreted as argument prefix
```
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Arguments of `#sum` does not match with other shortcuts methods
(count, average, minimum, and maximum).
This commit fix these two points:
* call `super` with only block arguments
First argument of `super` method, `Enumerable#sum`, is `identity`
and first argument of `AR::Calculations#sum` is `column_name`.
`Enumerable#sum` does not expect `column_name` to be passed.
* Change first argument of `sum` from array arguemnt to single
argument to match other shortcuts methods. When `sum` accept
array arguemnt, user can pass multi arguments and an exception is
raised from `calculate`.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Fixes #21488
[Sean Griffin & johanlunds]
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Stackprof output truncated.
```
TOTAL (pct) SAMPLES (pct) FRAME
23 (4.7%) 12 (2.4%) Hash#transform_keys
11 (2.2%) 11 (2.2%) block in Hash#transform_keys
30 (6.1%) 7 (1.4%) Hash#stringify_keys
```
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', 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('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}"
```
Before:
```
Calculating -------------------------------------
where with hash 2.796k i/100ms
where with string 4.338k i/100ms
-------------------------------------------------
where with hash 29.177k (± 1.5%) i/s - 148.188k
where with string 47.419k (± 2.8%) i/s - 238.590k
Comparison:
where with string: 47419.0 i/s
where with hash: 29176.6 i/s - 1.63x slower
Total Allocated Object: 85
```
After:
```
Calculating -------------------------------------
where with hash 2.895k i/100ms
where with string 4.416k i/100ms
-------------------------------------------------
where with hash 30.758k (± 2.0%) i/s - 156.330k
where with string 47.708k (± 2.6%) i/s - 238.464k
Comparison:
where with string: 47707.9 i/s
where with hash: 30757.7 i/s - 1.55x slower
Total Allocated Object: 84
```
|
| | | | |
| | | | |
| | | | | |
Sometimes opts passed in might respond to ==, e.g. `Arel::Nodes::Grouping`. In this case, `opts == :chain` returns `Arel::Nodes::Equality` which causes odd behaviour. Prefer `if :chain == opts` which guarantees that `Symbol#==` would be invoked. Alternatively consider `eql?`.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Since the strings are dynamically computed from a constant, the actual
strings we're creating are a known set. We can compute them ahead of
time, and reduce the number of allocations in that method.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
`in_batches` yields Relation objects if a block is given, otherwise it
returns an instance of `BatchEnumerator`. The existing `find_each` and
`find_in_batches` methods work with batches of records. The new API
allows working with relation batches as well.
Examples:
Person.in_batches.each_record(&:party_all_night!)
Person.in_batches.update_all(awesome: true)
Person.in_batches.delete_all
Person.in_batches.map do |relation|
relation.delete_all
sleep 10 # Throttles the delete queries
end
|