This project is archived and is in readonly mode.
Arel Union does not support #order or #limit
Reported by Steve Schwartz | April 10th, 2011 @ 08:18 PM
If we take two ActiveRecord::Relations
and join
them via union
:
rel_a = ActiveRecord::Relation.new(MyModel).where(:id => 3)
rel_b = ActiveRecord::Relation.new(MyModel).where(:id => 5)
new_rel = rel_a.union(rel_b)
new_rel.to_s #=> "#<Arel::Nodes::Union:0x3da6260>"
new_rel.to_sql #=> "( SELECT `my_models`.* FROM `my_models` WHERE (`my_models`.`id` = 3) UNION SELECT `my_models`.* FROM `my_models` WHERE (`top_items`.`id` = 5) )"
Ideally, we'd be able to sort and limit the resulting
UNION
results in the SQL. According to the MySQL docs
for the UNION operator, this should be possible (at least in
MySQL). We'd call it like this:
new_rel.order(:created_at).limit(5)
new_rel.to_sql #=> "( ( SELECT `my_models`.* FROM `my_models` WHERE (`my_models`.`id` = 3) ) UNION ( SELECT `my_models`.* FROM `my_models` WHERE (`top_items`.`id` = 5) ) ORDER BY `created_at` ASC LIMIT 5 )"
Currently, two things prevent this from being possible:
-
The
Arel::Nodes:Union
node inherits fromArel::Nodes::Binary
, with no additional methods, and as such, does not supportorder
orlimit
methods. -
The
Arel::Nodes::Union.to_sql
method should be wrapping both the:left
and the:right
Relation SQL strings in parentheses, so that theorder
andlimit
clauses may work on theUNION
itself, according to the MySQL docs.
Comments and changes to this ticket
-
Duke April 26th, 2011 @ 07:48 AM
I need this also. Interleaving ordering by post date and last commented date. I must do an ordered union.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>