mirror of https://github.com/rails/rails
Add regroup method
This commit is contained in:
parent
25df7a28fe
commit
cfc0144832
|
@ -1,3 +1,14 @@
|
||||||
|
* Add `#regroup` query method as a short-hand for `.unscope(:group).group(fields)`
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Post.group(:title).regroup(:author)
|
||||||
|
# SELECT `posts`.`*` FROM `posts` GROUP BY `posts`.`author`
|
||||||
|
```
|
||||||
|
|
||||||
|
*Danielius Visockas*
|
||||||
|
|
||||||
* PostgreSQL adapter method `enable_extension` now allows parameter to be `[schema_name.]<extension_name>`
|
* PostgreSQL adapter method `enable_extension` now allows parameter to be `[schema_name.]<extension_name>`
|
||||||
if the extension must be installed on another schema.
|
if the extension must be installed on another schema.
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ module ActiveRecord
|
||||||
:create_or_find_by, :create_or_find_by!,
|
:create_or_find_by, :create_or_find_by!,
|
||||||
:destroy_all, :delete_all, :update_all, :touch_all, :destroy_by, :delete_by,
|
:destroy_all, :delete_all, :update_all, :touch_all, :destroy_by, :delete_by,
|
||||||
:find_each, :find_in_batches, :in_batches,
|
:find_each, :find_in_batches, :in_batches,
|
||||||
:select, :reselect, :order, :in_order_of, :reorder, :group, :limit, :offset, :joins, :left_joins, :left_outer_joins,
|
:select, :reselect, :order, :regroup, :in_order_of, :reorder, :group, :limit, :offset, :joins, :left_joins, :left_outer_joins,
|
||||||
:where, :rewhere, :invert_where, :preload, :extract_associated, :eager_load, :includes, :from, :lock, :readonly,
|
:where, :rewhere, :invert_where, :preload, :extract_associated, :eager_load, :includes, :from, :lock, :readonly,
|
||||||
:and, :or, :annotate, :optimizer_hints, :extending,
|
:and, :or, :annotate, :optimizer_hints, :extending,
|
||||||
:having, :create_with, :distinct, :references, :none, :unscope, :merge, :except, :only,
|
:having, :create_with, :distinct, :references, :none, :unscope, :merge, :except, :only,
|
||||||
|
|
|
@ -446,6 +446,27 @@ module ActiveRecord
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Allows you to change a previously set group statement.
|
||||||
|
#
|
||||||
|
# Post.group(:title, :body)
|
||||||
|
# # SELECT `posts`.`*` FROM `posts` GROUP BY `posts`.`title`, `posts`.`body`
|
||||||
|
#
|
||||||
|
# Post.group(:title, :body).regroup(:title)
|
||||||
|
# # SELECT `posts`.`*` FROM `posts` GROUP BY `posts`.`title`
|
||||||
|
#
|
||||||
|
# This is short-hand for <tt>unscope(:group).group(fields)</tt>.
|
||||||
|
# Note that we're unscoping the entire group statement.
|
||||||
|
def regroup(*args)
|
||||||
|
check_if_method_has_arguments!(__callee__, args)
|
||||||
|
spawn.regroup!(*args)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Same as #regroup but operates on relation in-place instead of copying.
|
||||||
|
def regroup!(*args) # :nodoc:
|
||||||
|
self.group_values = args
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
# Applies an <code>ORDER BY</code> clause to a query.
|
# Applies an <code>ORDER BY</code> clause to a query.
|
||||||
#
|
#
|
||||||
# #order accepts arguments in one of several formats.
|
# #order accepts arguments in one of several formats.
|
||||||
|
|
|
@ -135,6 +135,13 @@ module ActiveRecord
|
||||||
assert relation.skip_preloading_value
|
assert relation.skip_preloading_value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "#regroup!" do
|
||||||
|
@relation = relation.group("foo")
|
||||||
|
|
||||||
|
assert relation.regroup!("bar").equal?(relation)
|
||||||
|
assert_equal ["bar"], relation.group_values
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def relation
|
def relation
|
||||||
@relation ||= Relation.new(FakeKlass)
|
@relation ||= Relation.new(FakeKlass)
|
||||||
|
|
|
@ -544,7 +544,7 @@ class RelationTest < ActiveRecord::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
%w( references includes preload eager_load group order reorder reselect unscope
|
%w( references includes preload eager_load group order reorder reselect unscope
|
||||||
joins left_joins left_outer_joins optimizer_hints annotate ).each do |method|
|
joins left_joins left_outer_joins optimizer_hints annotate regroup ).each do |method|
|
||||||
class_eval <<~RUBY
|
class_eval <<~RUBY
|
||||||
def test_no_arguments_to_#{method}_raise_errors
|
def test_no_arguments_to_#{method}_raise_errors
|
||||||
error = assert_raises(ArgumentError) { Topic.#{method}() }
|
error = assert_raises(ArgumentError) { Topic.#{method}() }
|
||||||
|
|
|
@ -117,6 +117,7 @@ The methods are:
|
||||||
* [`references`][]
|
* [`references`][]
|
||||||
* [`reorder`][]
|
* [`reorder`][]
|
||||||
* [`reselect`][]
|
* [`reselect`][]
|
||||||
|
* [`regroup`][]
|
||||||
* [`reverse_order`][]
|
* [`reverse_order`][]
|
||||||
* [`select`][]
|
* [`select`][]
|
||||||
* [`where`][]
|
* [`where`][]
|
||||||
|
@ -155,6 +156,7 @@ The primary operation of `Model.find(options)` can be summarized as:
|
||||||
[`references`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-references
|
[`references`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-references
|
||||||
[`reorder`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-reorder
|
[`reorder`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-reorder
|
||||||
[`reselect`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-reselect
|
[`reselect`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-reselect
|
||||||
|
[`regroup`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-regroup
|
||||||
[`reverse_order`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-reverse_order
|
[`reverse_order`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-reverse_order
|
||||||
[`select`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-select
|
[`select`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-select
|
||||||
[`where`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-where
|
[`where`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-where
|
||||||
|
@ -1122,7 +1124,37 @@ the SQL executed would be:
|
||||||
SELECT * FROM books WHERE out_of_print = 1 AND out_of_print = 0
|
SELECT * FROM books WHERE out_of_print = 1 AND out_of_print = 0
|
||||||
```
|
```
|
||||||
|
|
||||||
[`rewhere`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-rewhere
|
[`regroup`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-regroup
|
||||||
|
|
||||||
|
|
||||||
|
### `regroup`
|
||||||
|
|
||||||
|
The [`regroup`][] method overrides an existing, named `group` condition. For example:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Book.group(:author).regroup(:id)
|
||||||
|
```
|
||||||
|
|
||||||
|
The SQL that would be executed:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT * FROM books GROUP BY id
|
||||||
|
```
|
||||||
|
|
||||||
|
If the `regroup` clause is not used, the group clauses are combined together:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Book.group(:author).group(:id)
|
||||||
|
```
|
||||||
|
|
||||||
|
the SQL executed would be:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT * FROM books GROUP BY author, id
|
||||||
|
```
|
||||||
|
|
||||||
|
[`regroup`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-regroup
|
||||||
|
|
||||||
|
|
||||||
Null Relation
|
Null Relation
|
||||||
-------------
|
-------------
|
||||||
|
|
Loading…
Reference in New Issue