I want to be able to use two columns on one table to define a relationship. So using a task app as an example.
Attempt 1:
class Use
Rails 5:
you need to unscope the default where clause see @Dwight answer if you still want a has_many associaiton.
Though User.joins(:tasks) gives me
ArgumentError: The association scope 'tasks' is instance dependent (the scope block takes an argument). Preloading instance dependent scopes is not supported.
As it is no longer possible you can use @Arslan Ali solution as well.
Rails 4:
class User < ActiveRecord::Base
has_many :tasks, ->(user){ where("tasks.owner_id = :user_id OR tasks.assignee_id = :user_id", user_id: user.id) }
end
Update1: Regarding @JonathanSimmons comment
Having to pass the user object into the scope on the User model seems like a backwards approach
You don't have to pass the user model to this scope. The current user instance is passed automatically to this lambda. Call it like this:
user = User.find(9001)
user.tasks
Update2:
if possible could you expand this answer to explain what's happening? I'd like to understand it better so I can implement something similar. thanks
Calling has_many :tasks on ActiveRecord class will store a lambda function in some class variable and is just a fancy way to generate a tasks method on its object, which will call this lambda. The generated method would look similar to following pseudocode:
class User
def tasks
#define join query
query = self.class.joins('tasks ON ...')
#execute tasks_lambda on the query instance and pass self to the lambda
query.instance_exec(self, self.class.tasks_lambda)
end
end