I am porting a Rails app to Rails 4.2. This Rails app contains some rather complex manual SQL code in associations - partly due to DB optimizations (e.g. subselects instead of JOINs), partly due to no feasible alternative at the time of writing (Rails 3.0), partly surely due to lack of knowledge (I hope, at least - that would be easy to solve).
Example: An InternalMessage class. Messages can be sent between users (Recipients of an InternalMessage, and 'deletions' of messages, are stored in InternalMessagesRecipients, since there can be several) and they can be read, replied to, forwarded and deleted. The association looks like this:
class User < AR::Base
has_many :internal_messages,
:finder_sql => "SELECT DISTINCT(internal_messages.id), internal_messages.* FROM internal_messages " +
' LEFT JOIN internal_messages_recipients ON internal_messages.id=internal_messages_recipients.internal_message_id' +
' WHERE internal_messages.sender_id = #{id} OR internal_messages_recipients.recipient_id = #{id}',
:counter_sql => 'SELECT count(DISTINCT(internal_messages.id)) FROM internal_messages ' +
' LEFT JOIN internal_messages_recipients ON internal_messages.id=internal_messages_recipients.internal_message_id' +
' WHERE internal_messages.sender_id = #{id} OR internal_messages_recipients.recipient_id = #{id}'
# ...
end
The key part is the "OR" clause at the end - with this association I want to get both received and sent messages, which are joined with the user table seperately:
has_many :sent_messages, -> { where(:sender_deleted_at => nil) }, :class_name => 'InternalMessage', :foreign_key => 'sender_id' #, :include => :sender
has_many :internal_messages_recipients, :foreign_key => 'recipient_id'
has_many :rcvd_messages, :through => :internal_messages_recipients, :source => :internal_message, :class_name => 'InternalMessage'
since an InternalMessage might have several recipients (and can also be sent to the sender himself).
Q: How do I port this finder_sql
to a Rails 4.2 compatible has_many
definition?