-
-
Save weyus/1524987 to your computer and use it in GitHub Desktop.
I got it: - this appears to generate the correct query:
mr = MonitorRequest.arel_table
mr_alias = mr.alias("m_r")
sql = mr.project("user_id, fb_request_id").
from(mr_alias).
where(mr_alias[:current_state].eq(MonitorRequest::DENIED)).
where(mr_alias[:fb_id].eq(nil)).
where(mr_alias[:fb_name].eq(nil)).
where(mr_alias[:created_at].lt(1.week.ago)).
where(mr_alias[:user_id].not_eq(nil)).
where(mr_alias[:fb_request_id].not_eq(nil)).
where(MonitorRequest.where(mr[:current_state].eq(MonitorRequest::PENDING)).
where(mr[:fb_request_id].eq(mr_alias[:fb_request_id])).exists).to_sql
generates:
SELECT user_id, fb_request_id
FROM "monitor_requests" "m_r"
WHERE "m_r"."current_state" = 'denied'
AND "m_r"."fb_id" IS NULL
AND "m_r"."fb_name" IS NULL
AND "m_r"."created_at" < '2011-12-20 20:25:48.538148'
AND "m_r"."user_id" IS NOT NULL
AND "m_r"."fb_request_id" IS NOT NULL
AND EXISTS (SELECT "monitor_requests".* FROM "monitor_requests" WHERE "monitor_requests"."current_state" = 'pending' AND "monitor_requests"."fb_request_id" = "m_r"."fb_request_id")
Which is more readable - the raw SQL or Arel? Not sure.
The Arel is unfortunately needlessly complex given that the outer query conditions don't need to use the alias in the raw SQL.
The alias is really only needed on the condition in the correlated subquery.
But you have to use mr_alias in the outer query or you get this Postgres error - 'PGError: ERROR: invalid reference to FROM-clause entry for table "monitor_requests"' Lame.
Since you're referencing the main query (mr) in the exists, I don't know how to make it happen...Here's something you CAN do
I would normally approach the problem as two queries, or go raw SQL.