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>`
|
||||
if the extension must be installed on another schema.
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ module ActiveRecord
|
|||
:create_or_find_by, :create_or_find_by!,
|
||||
:destroy_all, :delete_all, :update_all, :touch_all, :destroy_by, :delete_by,
|
||||
: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,
|
||||
:and, :or, :annotate, :optimizer_hints, :extending,
|
||||
:having, :create_with, :distinct, :references, :none, :unscope, :merge, :except, :only,
|
||||
|
|
|
@ -446,6 +446,27 @@ module ActiveRecord
|
|||
self
|
||||
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.
|
||||
#
|
||||
# #order accepts arguments in one of several formats.
|
||||
|
|
|
@ -135,6 +135,13 @@ module ActiveRecord
|
|||
assert relation.skip_preloading_value
|
||||
end
|
||||
|
||||
test "#regroup!" do
|
||||
@relation = relation.group("foo")
|
||||
|
||||
assert relation.regroup!("bar").equal?(relation)
|
||||
assert_equal ["bar"], relation.group_values
|
||||
end
|
||||
|
||||
private
|
||||
def relation
|
||||
@relation ||= Relation.new(FakeKlass)
|
||||
|
|
|
@ -544,7 +544,7 @@ class RelationTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
%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
|
||||
def test_no_arguments_to_#{method}_raise_errors
|
||||
error = assert_raises(ArgumentError) { Topic.#{method}() }
|
||||
|
|
|
@ -117,6 +117,7 @@ The methods are:
|
|||
* [`references`][]
|
||||
* [`reorder`][]
|
||||
* [`reselect`][]
|
||||
* [`regroup`][]
|
||||
* [`reverse_order`][]
|
||||
* [`select`][]
|
||||
* [`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
|
||||
[`reorder`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-reorder
|
||||
[`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
|
||||
[`select`]: https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-select
|
||||
[`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
|
||||
```
|
||||
|
||||
[`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
|
||||
-------------
|
||||
|
|
Loading…
Reference in New Issue