Sto trasferendo un'applicazione Rails a Rails 4.2. Questa app Rails contiene un codice SQL manuale piuttosto complesso nelle associazioni - in parte a causa dell'ottimizzazione del database (ad es. Sottoselezioni anziché JOINs), in parte a causa di un'alternativa non fattibile al momento della scrittura (Rails 3.0), in parte sicuramente a causa della mancanza di conoscenza (Spero, almeno, che sia facile da risolvere).Il porting complicato ha_molte relazioni con Rails> 4.1 (senza finder_sql)
Esempio: una classe InternalMessage. I messaggi possono essere inviati tra utenti (Destinatari di un messaggio interno e "cancellazioni" di messaggi, sono memorizzati in InternalMessagesRecipients, poiché possono esserci diversi) e possono essere letti, replicati, inoltrati e cancellati. L'associazione si presenta così:
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
La parte fondamentale è la "O" clausola alla fine - con questa associazione voglio ottenere sia messaggi ricevuti e inviati, che sono uniti con la tabella utente separatamente:
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'
poiché un InternalMessage potrebbe avere più destinatari (e può anche essere inviato al mittente stesso).
Q: Come posso trasferire questo finder_sql
a una definizione di Rails 4.2 has_many
?
Ovviamente, questo è inferiore se si desidera la memoizzazione dei risultati, in particolar modo lavorano con il 'reload'. C'è un modo per ottenere binari per mantenere queste relazioni senza la chiave esterna? – duane