Vorrei inviare una PR per aggiungere un metodo get_like a PluginStore.
get_like recupererà tutti i record per un determinato plugin, la cui chiave inizia con la stessa parola.
Caso d’uso
Se un plugin ha due o più entità che desidera memorizzare, ad esempio mele e arance, i dati verranno archiviati come apple_1, apple_2… e orange_1, orange_2 da un plugin denominato fruits.
Per recuperare tutte le arance, è possibile chiamare semplicemente PluginStore.get_like(‘fruits’, ‘orange’) ecc.
Cosa ne pensano il team e gli sviluppatori di plugin?
Non credo di aver mai avuto personalmente bisogno di questo pattern. L’hai visto in plugin pubblici o solo in quello che stai creando?
Inoltre, non è troppo lungo da digitare:
PluginStoreRow.where("plugin_name = 'fruits' AND key LIKE 'orange%')
Ti consiglio di aggiungere una funzione o una classe di utilità al tuo plugin se lo fai spesso. Assicurati anche di avere indici appropriati per queste query.
Stavo lavorando a questa funzionalità per il plugin custom-wizards e volevo recuperare tutti gli stregoni.
La chiave utilizzata è una stringa unica per ogni stregone. Questo caso è stato gestito recuperando tutte le righe per il plugin e filtrandole in base al value, il che va bene per un numero ridotto di record ma non è ideale per un plugin di grandi dimensioni. Sembra che plugin_store_rows sia destinato a memorizzare dati di tipo impostazione per il plugin.
Personalmente, penso che questo apra la possibilità di memorizzare dati di tipo non-impostazione nella tabella plugin_store_rows.
In generale, ti consiglio di creare le tue tabelle tramite migrazioni se PluginStoreRow non può essere interrogato nel modo desiderato. Questa pratica è ormai comune in diversi plugin e funziona egregiamente!
Tuttavia, viene ancora utilizzato in alcuni contesti, inclusa la codebase core di Discourse stessa, ad esempio nel modello Reviewables.
Anch’io utilizzo questo modello in numerosi plugin.
Il motivo principale per cui si usa questo modello è che la tabella plugin_store_rows è utilizzata da più plugin (e da alcuni servizi core), quindi le colonne identificative, ovvero id e plugin_name, non possono essere impiegate per l’identificazione interna all’interno di ciascun sistema che utilizza PluginStore. Di conseguenza, nel campo key viene adottato un sistema basato su stringhe.
Per quanto riguarda la modifica della struttura del database all’interno di un plugin, @gdpelican ha un ottimo post a riguardo:
Personalmente, sono ancora molto cauto nel farlo, poiché lavorando su un plugin di terze parti non hai il controllo sul namespace, sulla rimozione del tuo plugin o su eventuali modifiche conflittuali apportate al core di Discourse.
Come menziona @gdpelican, devi fornire un modo per gli utenti del plugin per rimuovere le modifiche al database se disinstallano il plugin.
Fornisci un metodo per gli utenti per pulire le modifiche al database se non vogliono più il tuo plugin. L’ho fatto con un task rake.
Ritengo che questo sia troppo tecnico per la maggior parte degli utenti dei plugin e rappresenti un rischio se non sono a conoscenza di questo dettaglio.
Inoltre, non ho ancora riscontrato un reale bisogno di uscire dai limiti di PluginStore e CustomFields.
Detto questo, personalmente sarei favorevole all’introduzione di un nuovo metodo in PluginStore, in quanto trovo utile questo modello.
@david Sarei interessato anche alle tue riflessioni su quanto sopra.
Come ha detto @eviltrout, stiamo utilizzando migrazioni e tabelle dedicate in diversi plugin, con grande successo. La possibilità di imporre vincoli a livello di database ha contribuito a migliorare le prestazioni (ricerche in qualsiasi colonna) e l’integrità dei dati (grazie agli indici univoci). Questi due aspetti si sono rivelati particolarmente importanti alla scala di alcuni dei nostri clienti ospitati: non è qualcosa che avevo considerato prima di unirmi al team.
Il primo plugin significativo su cui ho lavorato è stato chat-integration, e ho implementato un “fake activerecord” piuttosto complicato, che si appoggia allo store dei plugin. A posteriori, le tabelle dedicate sarebbero state una scelta molto migliore, e potrei valutare di migrare il plugin in quella direzione in futuro.
Concordo quando si tratta di modificare le tabelle core. Aggiungere o modificare colonne su tabelle esistenti potrebbe avere conseguenze impreviste in futuro e rimarrà anche se il plugin viene disinstallato. Sconsiglio vivamente di farlo.
Le tabelle dedicate, d’altra parte, presentano un rischio piuttosto basso. Se il plugin viene disinstallato, rimarranno semplicemente senza effetti collaterali negativi (purché non vengano introdotti vincoli di chiave esterna). Lasciare dati in giro non è “peggio” rispetto all’utilizzo dello store dei plugin.
Per quanto riguarda la pulizia, potremmo valutare di fornire task rake che “annullino” le migrazioni dei plugin per effettuare la pulizia. Ma a essere onesti, non credo che verranno utilizzati molto. La mia ipotesi è che le persone raramente disinstallino i plugin e, quando lo fanno, preferiscano mantenere i dati nel caso volessero reinstallarli in futuro.
In quanto autore di quel codice, dovrei forse chiarire un po’ la questione. Gli ID di priorità sono costanti e non dati relazionali. Raccomanderei assolutamente di non utilizzare something_id quando gli ID non sono noti in anticipo. In questo caso, ogni priorità è considerata come un singleton, e ho pensato che qualsiasi tabella avrei creato sarebbe stata essenzialmente una copia dello PluginStore!