Active Record find_by_sql and rspec expect block. New ids are created for no reason

432 views Asked by At

I am working on a complex SQL query with rails 4.2.1

def self.proofreader_for_job(job)
  User.find_by_sql(
    "SELECT * FROM users
     INNER JOIN timers 
     ON users.id = timers.proofreader_id
     INNER JOIN tasks
     ON tasks.id = timers.task_id
     WHERE tasks.job_id = #{job.id}")
end

My schema is (jobs has_many tasks, tasks has_many timers, and a timer belongs_to a user(role: proofreader) through the foriegn key proofreader_id)

The issue is that when I call the method it is returning what is the correct user's email and attributes but the id doesn't match.

For exeample User.proofreader_for_job(job) returns

[#<User id: 178, email: "[email protected]">]

[email protected] is the correct email, but I don't have a user in my db with an id of 178.

User.all just returns

 [#<User id: 12, email: "[email protected]">,
 #<User id: 11, email: "[email protected]">]

I noticed the issue in my rspec tests, but it happens on both development and test environments.

Does anyone have any idea why my methods is returning a user with such a high id. Is this done by design, if so why?

Thank you.

1

There are 1 answers

0
Corbin Page On BEST ANSWER

Since you're doing 'Select *', your statement will return all columns for each of the tables in the JOIN statement. So when you're casting the output from the SQL statement to a User type, I think the wrong 'id' column is being grabbed for the User id (likely the timers or tasks table).

Try explicitly specifying the columns to return like the below statement:

User.find_by_sql(
    "SELECT users.id, users.email FROM users
    INNER JOIN timers 
    ON users.id = timers.proofreader_id
    INNER JOIN tasks
    ON tasks.id = timers.task_id
    WHERE tasks.job_id = #{job.id}")
end