Select clause in a repository?



I’m struggling again with my repository, this time let me describe a simplified version of my real model. I have a courses table, a users table, and a interacts table. As you can guess, users can interact with courses. Let’s assume the following tables:

courses (id, name, created_at, updated_at)
interacts (course_id, user_id, created_at, updated_at)

I want to find the list of courses for which a given user does not interact:

                                { course_id: :id },
                                { interacts[:user_id].qualified => user_id })
                     .where(interacts[:course_id].qualified => nil)

If left as-is, created_at and updated_at make the query fail with PG::AmbiguousColumn. I tried to use a select but I get strange errors:

.select(:id, :name)
# => TypeError: wrong argument type Symbol (expected Array)

.select([:id, :name])
# => TypeError: no implicit conversion of Symbol into IO

.select(*courses.project(:id, :name))
# => TypeError: can't convert Course into time interval

Obviously, I’m doing it wrong. I also tried to qualify things here and there, but to no avail.

How can I solve that?


Could you try to use #project instead of #select? Something like this:

repo.project(:id, :name)


You’re right, I had to use the projection method, this is what the query is actually supposed to look like (I also had to change the left_join parameters because the second hash is not what I thought it was):

                                { course_id: :id,
                                  interacts[:user_id].qualified => user_id })
                     .where(interacts[:course_id].qualified => nil)
                     .project(:id, :name, :description)



project is an alias of select so, uhm, it should work the same. In rom 3 though, there’s a problem with select because repos are using relation decorator objects, and select is actually a method defined on Kernel so…luckily this won’t be an issue in rom 4 as repo relation decorators are gone there.