2013-04-11 16 views
12

Sto lavorando a un progetto in questo momento che ha un requisito piuttosto insolito e spero di ottenere qualche consiglio sul modo migliore per gestirlo o anche su alcuni suggerimenti per informazioni che possono aiutarmi a costruire una soluzione.Creazione dinamica di modelli e/o tabelle in Rails

Ok, quindi questo è quello che devo fare. L'applicazione archivia e gestisce vari tipi di file multimediali, ma ogni distribuzione dell'applicazione ha requisiti di metadati completamente diversi per i file multimediali.

Questi metadati possono contenere un numero arbitrario di campi di tipi diversi (testo a riga singola, testo a più righe, caselle di controllo, valori selezionati, ecc.) E spesso richiedono convalida in particolare convalide di presenza e unicità.

L'applicazione deve essere in grado di recuperare facilmente i valori e , soprattutto, deve essere in grado di gestire le funzionalità di ricerca complete su questi campi.

Un'opzione che ho preso in considerazione era l'utilizzo di una disposizione di elenchi di proprietà in cui la tabella del database conteneva semplicemente un nome e un valore di proprietà per ciascun campo di metadati di ciascun file multimediale. Tuttavia, durante la prototipazione di questa soluzione è apparso subito evidente che semplicemente non sarebbe stato abbastanza efficiente per la ricerca e il recupero di record, in particolare quando il database può essere abbastanza grande per es. una distribuzione recente aveva 3000 file multimediali e c'erano oltre 20 campi di metadati. Inoltre, le query per effettuare una ricerca e recuperare i record rilevanti sono diventate rapidamente molto complesse.

Un'altra opzione che il sistema sta attualmente utilizzando è che la configurazione dei metadati viene definita in anticipo e durante la distribuzione viene eseguita una migrazione per creare una tabella e un modello con un nome standard in modo che il modello di supporto possa essere associato al il sistema quindi usa. Questo in genere funziona abbastanza bene, ma causa alcuni problemi significativi di implementazione e test.

Ad esempio, la scrittura dei test di unità diventa molto più difficile quando non si conosce la configurazione fino alla distribuzione. Anche se potrei scrivere una configurazione di esempio e testare il codice in questo modo, non mi consentirà di testare i requisiti specifici di una particolare distribuzione.

Allo stesso modo, in fase di sviluppo, attualmente mi richiede di copiare una migrazione dalla configurazione nella cartella principale, eseguirla, eseguire tutti i test e lo sviluppo e quindi devo ricordare di eseguire il rollback e rimuovere quella migrazione dal principale cartella in modo che l'applicazione sia in uno stato standard. Questo diventa particolarmente difficile quando sto correggendo i bug e ho bisogno di avere l'applicazione in una configurazione specifica per scopi di test e di debug. Cercare di passare da una configurazione all'altra diventa un vero incubo.

Idealmente, ciò che vorrei è poter creare dinamicamente la tabella e il modello incluse le convalide, ecc. Da un file di configurazione all'avvio del server. Sarebbe anche meglio se potessi mantenere più setup di metadati in un database con ciascuno con la propria tabella, in modo che tutto ciò che devo fare per passare da uno all'altro sia modificare il file di configurazione che l'applicazione sta attualmente utilizzando.

Sono sicuro che questo può essere fatto con Rails ma ci sono pochissime informazioni che sono stato in grado di trovare che possono indicarmi la giusta direzione su come costruirlo durante le mie ricerche negli ultimi giorni così qualsiasi aiuto o suggerimento sarebbe molto apprezzato!

risposta

1

Quello che hai descritto suona esattamente come i requisiti di definizione per un meccanismo di memorizzazione non tradizionale che utilizzava l'archiviazione dei valori-chiave.

Sento questo da:

  • 'requisiti di metadati completamente diverse' e '- 'numero arbitrario di campi di tipo diverso' - archivi di dati chiave-valore spesso non hanno schema e sono molto flessibili per diversi registra layout che cambiano al volo.

  • L'applicazione deve essere in grado di recuperare facilmente i valori e, soprattutto, deve essere in grado di gestire le funzionalità di ricerca complete su questi campi. Gli archivi di valori-chiave sono resi estremamente efficienti nel recuperare e filtrare le righe per le query.

'Un accordo elenco di proprietà in cui la tabella del database semplicemente conteneva un nome di proprietà e valore per ciascun metadati' è fondamentalmente un negozio di valore chiave.

Alcune opzioni sono:

+1

Sì, questo è stato anche il mio primo pensiero ed era quello che intendevo fare in origine. Ma quando ho implementato una soluzione prototipo, una ricerca di base solo il recupero dei campi era circa 10 volte più lenta di una normale soluzione basata su tabelle. E quando aggiungi il costo delle ricerche in esecuzione per filtrare i record, diventa rapidamente proibitivo, soprattutto considerando che la funzionalità di ricerca è abbastanza fondamentale per il funzionamento dell'applicazione complessiva. – richard

3

Se ho capito bene, Rails ha alcuni trucchi nifty per lui lp tu risolvi questi problemi

Nell'ORM ActiveRecord è possibile modellare ciò che si sta tentando di fare in un database relazionale, utilizzando il modello di ereditarietà a tabella singola o con polymorphic associations (... un po 'più complesso ma anche più flessibile). Un'associazione polimorfica consente a un modello di appartenere a tipi diversi di altri modelli. C'è un railscast recente su questo argomento ma non lo collegherò poiché richiede un abbonamento a pagamento.

Sul lato dello schieramento, sembra che tu stia facendo un sacco di cose manualmente, che è il modo giusto di iniziare finché non emerge un modello. Dopo aver iniziato a visualizzare il modello, sono disponibili eccellenti programmi per l'automazione di configurazione, generazione e distribuzione come Capistrano, OpsCode Chef e Puppet, solo per citarne alcuni. Potresti anche trarre vantaggio dall'integrazione della configurazione e della distribuzione con il repository del codice sorgente per ottenere un flusso di lavoro migliore. Ad esempio, con Git è possibile definire topic branches per il tipo di file multimediale e avere una configurazione diversa in ogni ramo che corrisponde al ramo dell'argomento.

Si consiglia di controllare l'eccellente libro di Martin Fowler 'PoEAA' e alcuni degli argomenti sul suo website. Spero che questa risposta aiuti anche se la risposta è piuttosto generica. La tua domanda è molto ampia e non ha una risposta semplice.

1

posso vedere alcuni modi ragionevoli per avvicinarsi a questo, a seconda delle vostre esigenze:

  1. Se non è proibitivo per scrivere modelli e migrazioni per ognuno dei vostri set di metadati, poi andare avanti e generare un modello e migrazione per ognuno. Quindi, nel file di configurazione per l'ambiente, ad es. config/development.rb - carica il modello desiderato per quell'ambiente in una costante globale (forse ModelConfiguration::MetadataModel all'interno di lib/model_configuration.rb).Scrivi il resto della tua app per interagire solo con il tuo modello di metadati tramite questa costante.

    Questo approccio è abbastanza efficiente; il suo unico vero svantaggio è che stai creando una tabella aggiuntiva nel tuo database per ogni modello. Al momento dell'esecuzione, i modelli non utilizzati non vengono nemmeno caricati, quindi non influiscono affatto sulle prestazioni.

  2. D'altra parte, è possibile avere così tanti modelli di metadati che questo approccio è troppo doloroso da considerare, o è possibile che non si conosca il modello dei metadati prima del tempo. In questo caso, vorrei fare quanto segue:

    • Avere il config caricare il momento desiderato modello di configurazione in un costante globale in qualche forma facilmente digeribile (forse ModelConfiguration::ModelJSON).

    • Scrive una singola classe di modello che, quando caricata, cerca in ModelConfiguration::ModelJSON e chiama un metodo di classe per installare i campi e le convalide appropriati su se stesso da questa configurazione.

    • Scrivere un'attività Rake per creare una tabella che corrisponda alla configurazione. Vedi http://edgeguides.rubyonrails.org/command_line.html#custom-rake-tasks per un resoconto rapido su come scrivere un'attività Rake. L'approccio più semplice è probabilmente quello di generare una migrazione una tantum dalla tua configurazione e quindi eseguire quella migrazione (chiamando .up su di essa). Il rovescio della medaglia qui è che la migrazione una tantum sparirà dopo l'esecuzione dell'attività, quindi perderai l'accesso a rake db:rollback.

    Questo approccio è molto generale, e il suo più grande vantaggio è che non hai bisogno di un cambiamento di codice al fine di ottenere un cambiamento di configurazione, che ti dà un sacco di libertà nel modo in cui memorizzare e distribuire le configurazioni .

2

ogni distribuzione dell'applicazione ha completamente diverse requisiti di metadati per i file multimediali.

Si consiglia di utilizzare mongoDB per il database e Mongoid per il proprio ORM. Questo ti darà la flessibilità di cui hai bisogno per modificare lo schema secondo necessità senza orribili manipolazioni dello schema, modelli/tabelle dinamici e tutto ciò che è orrore.

L'applicazione ha bisogno di essere in grado di recuperare facilmente i valori e la maggior parte deve soprattutto essere in grado di gestire funzionalità complete a cercare su questi campi.

Questo è un problema di ricerca piuttosto che un problema di database. Raccomando di provare le funzionalità di ricerca full-text nell'ultima versione di mongoDB. Se questo non soddisfa le tue esigenze, prova con elasticsearch in congiunzione con la gemma Tire (un client elasticsearch che si integra bene con Rails).

Problemi correlati