enjaku enjaku - 2 months ago 14
Ruby Question

concatenate activerecord relations using "or" condition

I have two queries

urgent = MassScanTask.joins(:mass_scan_list).where("mass_scan_lists.urgent = ? AND mass_scan_lists.enabled = ?", true, true).order("updated_at DESC")
not_urgent = MassScanTask.joins(:mass_scan_list).where("mass_scan_lists.urgent = ? AND mass_scan_lists.enabled = ? ", false, true).order("updated_at ASC")


how can I get them all together
urgent + not_urgent
using single query? Or maybe there is some method to add one to another. I have already tried
concat
but it returns array and I need activerecord relations, I have also tried
merge
but it returns nothing.

Answer

So, looking at these queries, it seems that you want all enabled rows from the mass_scan_lists table, but the only difference is the ordering. You want all urgent to come first, ordered byupdated_at descand then havenon-urgentordered byupdated_at`.

So, I would just use some custom SQL in the order statement. You don't specify what RDBMS you are using, but if it is PostgreSQL, it would look like:

tasks = MassScanTask \ .joins(:mass_scan_list) \ .where(mass_scan_lists: { enabled: true }) \ .order('case urgent when true then -1 * extract(epoch from updated_at) else extract(epoch from updated_at) end')

This order clause uses a CASE statement, which is not supported in all DBs, but whatever you are using likely has a similar clause.