I have the following models. Users have UserActions, and one of the possible UserActions can be ContactAction (UserAction is polymorphism). There are other actions like LoginAction etc. So,
class User <AR :: Base
has_many: contact_requests,: class_name => "ContactAction"
has_many: user_actions
has_many_polymorphs: user_actionables,: from => [: contact_actions, ...],: through =>: user_actions
end
class UserAction <AR :: Base
belongs_to: user
belongs_to: user_actionable,: polymorphic => true
end
class ContactAction <AR :: Base
belongs_to: user
named_scope: pending, ...
named_scope: active, ...
end
The idea is that ContactAction combines two users (with other consequences in the application) and always has a reception and sending. At the same time, ContactAction can have different states, for example. expired, pending, etc.
I can say @user.contact_actions.pending or @user.contact_requests.expired to list all pending / expired requests sent or received by the user. It works great.
Now I would like to combine both types of ContactAction. That is @user.contact_actions_or_requests . I tried the following:
class User
def contact_actions_or_requests
self.contact_actions + self.contact_requests
end
# or
has_many: contact_actions_or_requests,: finder_sql => ...,: counter_sql => ...
end
but they all have a problem that it is not possible to use additional crawlers or named_scopes over the association, for example. @user.contact_actions_or_requests.find(...) or @user.contact_actions_or_requests.expired .
Basically, I need a way to express a 1: n association, which has two different paths. One of them is User -> ContactAction.user_id , the other is User -> UserAction.user_id -> UserAction.user_actionable_id -> ContactAction.id . And then add the results (ContactActions) to a single list for further processing using named_scopes and / or finders.
Since I need this association in literally dozens of places, it would be a big problem to write (and support!) My own SQL for each case.
I would prefer to solve this problem in Rails, but I am also open to other suggestions (e.g. PostgreSQL 8.3 procedure or something similar). The important thing is that in the end, I can use the convenient functions of Rails, such as any other association, and, more importantly, also nest them.
Any ideas would be greatly appreciated.
Thanks!
To give a kind of answer to my own question:
I will probably resolve this using the database view, and add the appropriate associations if necessary. For the above, I can
- use SQL in finder_sql to create the view,
- name it "contact_actions_or_requests",
- modify the SELECT clause to add the user_id column,
- add application / models / ContactActionsOrRequests.rb,
- and then add "has_many: contact_actions_or_requests" to user.rb.
I donβt know how I will handle record updates - this seems impossible with the view - but maybe this is the first run.