Has_many association where the source model can be in several columns

Hello all,

I have an application dealing with User and Transaction objects, each
transaction going from a source user to a target user.

I have defined the following associations in user.rb :

has_many :transactions_as_source, :class_name => “Transaction”, :as
=> :source
has_many :transactions_as_target, :class_name => “Transaction”, :as
=> :target

and this is working fine, but I’m looking for a way to define
“has_many :transactions” to get all the transactions having the user
as a source OR a target, i.e. something like:

has_many :transactions, :finder_sql => ‘SELECT * FROM transactions
WHERE source_id = #{id} OR target_id = #{id}’

but without resorting to finder_sql (as with this definition I cannot
cascade additional queries such as
current_user.transactions.sum(:amount) or
current_user.transactions.find(…).

Thanks,

Nicolas

Hum, it looks like you are about to enjoy the has_many through
polymorphism troubles…

Check here : has_many :through - The other side of polymorphic :through associations

My only personal advice will be : be VERY careful with each letter
(specifically the “s”) you will use because if it does not work Rails
won’t say a word.

H

nj wrote:

Hello all,

I have an application dealing with User and Transaction objects, each
transaction going from a source user to a target user.

I have defined the following associations in user.rb :

has_many :transactions_as_source, :class_name => “Transaction”, :as
=> :source
has_many :transactions_as_target, :class_name => “Transaction”, :as
=> :target

and this is working fine, but I’m looking for a way to define
“has_many :transactions” to get all the transactions having the user
as a source OR a target, i.e. something like:

has_many :transactions, :finder_sql => ‘SELECT * FROM transactions
WHERE source_id = #{id} OR target_id = #{id}’

but without resorting to finder_sql (as with this definition I cannot
cascade additional queries such as
current_user.transactions.sum(:amount) or
current_user.transactions.find(…).

Thanks,

Nicolas