Domanda

Ho bisogno di connettersi a un database legacy e tirare un sottoinsieme di dati da una tabella che utilizza il modello entità-attributo-valore per memorizzare le informazioni di un contatto. La tabella è simile al seguente:

subscriberid     fieldid     data
1                2           Jack
1                3           Sparrow
2                2           Dan
2                3           Smith

dove fieldid è una chiave esterna a una tabella che elenca fields campi personalizzati un determinato cliente può avere (ad esempio nome, cognome, telefono). Lo SQL coinvolto è piuttosto peloso come devo unire la tabella con se stessa per ogni campo che voglio indietro (al momento ho bisogno di 6 campi), così come l'adesione ad una lista di contatti maestro che si basa su l'utente corrente.

L'SQL è qualcosa di simile:

select t0.data as FirstName, t1.data as LastName, t2.data as SmsOnly
  from subscribers_data t0 inner join subscribers_data t1 
    on t0.subscriberid = t1.subscriberid
  inner join subscribers_data t2 
    on t2.subscriberid = t1.subscriberid
  inner join list_subscribers ls 
    on (t0.subscriberid = ls.subscriberid and t1.subscriberid = ls.subscriberid)
  inner join lists l
    on ls.listid = l.listid
  where l.name = 'My Contacts'
    and t0.fieldid = 2 
    and t1.fieldid = 3;

Come devo fare per la manipolazione di questo con la mia applicazione RoR? Vorrei abstracat questa via ed essere in grado di utilizzare il normale "notazione punto" per tirare fuori gli attributi ancora. Per fortuna i dati è di sola lettura per il prossimo futuro.

È stato utile?

Soluzione

Questo è esattamente ciò che è stato progettato per #find_by_sql. Vorrei reimplementare #find di fare ciò che è necessario fare, qualcosa di simile a questo:

class Contact < ActiveRecord::Base
  set_table_table "subscribers_data"

  def self.find(options={})
    find_by_sql <<EOS
      select t0.data as FirstName, t1.data as LastName, t2.data as SmsOnly
        from subscribers_data t0 inner join subscribers_data t1 
          on t0.subscriberid = t1.subscriberid
        inner join subscribers_data t2 
          on t2.subscriberid = t1.subscriberid
        inner join list_subscribers ls 
          on (t0.subscriberid = ls.subscriberid and t1.subscriberid = ls.subscriberid)
        inner join lists l
          on ls.listid = l.listid
        where l.name = 'My Contacts'
          and t0.fieldid = 2 
          and t1.fieldid = 3;
    EOS
  end
end

Le istanze di contatto avranno #FirstName e #LastName come attributi. Si potrebbe rinominare loro come AR si aspetta troppo, in modo tale che #first_name e #last_name avrebbe funzionato. È sufficiente modificare le clausole durante la vostra SELECT.

Altri suggerimenti

Io non sono sicuro che è totalmente germano alla tua domanda, ma si potrebbe desiderare di dare un'occhiata a MagicModel . E 'in grado di generare modelli per, sulla base di un database legacy. Potrebbe abbassare la quantità di lavoro che devi fare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top