Question

We need to retrieve logs for customer comm record in our rails app. The condition in plain english is logs for customer_comm_record based on:

#1. the sales_id in customer comm record's customers is equal to current user id
#2. the sales_id in customer comm record's customer's project is equal to the current user id. 

The SQL code for #1 could be (SQL#1):

Log.joins(:customer_comm_record =>:customer).where('customers.sales_id = ?', session[:user_id])

SQL code for #2 could be (SQL#2):

Log.joins(:customer_comm_record =>{ :customer => :projects}).where('projects.sales_id = ?', session[:user_id])

Here is what we come up (SQL#3) in one line:

Log.joins(:customer_comm_record =>{ :customer => :projects}).where('customers.sales_id = ? OR projects.sales_id = ?', session[:user_id], session[:user_id])

The SQL code returned by above in rails console is (replacing session[:user_id] with 1) :

 SELECT "logs".* FROM "logs" INNER JOIN "customer_comm_records" ON "customer_comm_records"."id" = "logs"."customer_comm_record_id" INNER JOIN "customers" ON "customers"."id" = "customer_comm_records"."customer_id" INNER JOIN "projects" ON "projects"."customer_id" = "customers"."id" WHERE (customers.sales_id = 1 OR projects.sales_id = 1)

The question is weather SQL#3 == SQL#1 UNION SQL#2. Can someone answer the question? If it is not, what's the right one? Thanks.

Was it helpful?

Solution

The only differences are:

  • The first method will return duplicate entries where the sales_id for the customer and project both match the users id.
  • The second method might not return records where a customer with a matching sales_id does not have a project (no projects.customer_id for that customer).

The last difference only matters if a customer does not necessarily have any projects. Otherwise, the second method is better because it avoids dealing with duplicates.

If a customer does not always have a project, a simple workaround would be to use includes instead of joins:

Log.includes(:customer_comm_record =>{ :customer => :projects}).
    where('customers.sales_id = :id OR projects.sales_id = :id', id: session[:user_id])

This will force a LEFT JOIN and will return customers regardless of whether they are associated with a project.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top