Plugin Discourse e configurazione Rails 6 config/initializers Domanda

Ehi, esperti di plugin Discourse,

Una rapida domanda sui plugin di Discourse e sugli initializer di Rails.

Se un plugin di Discourse ha una directory chiamata “config” e una sottodirectory sotto “config” chiamata “initializers”, l’app Rails di Discourse legge tutti i file di initializer del plugin nella directory “initializers” come fa Rails 6?

Il motivo per cui chiedo è che sto scrivendo da zero un’applicazione Rails 6 “back office” (solo Rails, senza EmberJS o altri framework JS sopra) per un cliente e ho una directory sotto initializers come questa:

./config/initializers/client/

… e tutti gli initializer specifici del cliente si trovano nella sottodirectory “client”.

Rails 6 legge tutti i file sotto la directory standard degli initializer (anche le sottodirectory); quindi mi chiedevo se i plugin di Discourse, con una struttura di directory simile per gli initializer, si comportino come Rails 6 e leggano tutti gli initializer nel plugin in un modo come questo:

./plugins/my_plugin/config/initializers/myclient/
      client_initializer1.rb
      client_initializer2.rb
      client_initializer3.rb

… senza registrare queste risorse nel file plugin.rb?

Grazie!

PS: Ho esaminato circa 10 plugin di Discourse su GitHub e nessuno di quelli che ho visto aveva initializer sotto la directory config. Ecco perché ho deciso di postare la domanda (e il mio ambiente di sviluppo Rails non è attualmente configurato per Discourse, è tutto configurato per il cliente).

2 Mi Piace

Voglio anche sapere qual è la differenza tra un plugin Discourse e un comune motore Rails. Ho dato un’occhiata al codice sorgente, ma non ho capito molto.

Dopo aver dato un’occhiata veloce a Ruby on Rails Guides: Configuring Rails Applications
penso che plugin.rb sia in qualche modo la stessa cosa. La maggior parte dei plugin di dimensioni consistenti lo utilizza come punto di ingresso per la logica piuttosto che come logica vera e propria.

Sì, ho letto spesso quella guida di Rails ultimamente. In sostanza, sono “a posto” con il modo in cui funziona la configurazione di Rails 6 (sto ancora imparando, ma mi sento sempre più a mio agio di giorno in giorno).

Mi chiedo solo se possiamo usare la stessa struttura in un plugin di Discourse (per gli initializer), se Rails leggerà gli initializer nelle sottodirectory come fa in Rails 6; oppure se dobbiamo registrare la directory degli initializer del plugin come “asset” di configurazione (per mancanza di un termine migliore) in plugin.rb.

Ieri stavo leggendo informazioni sui plugin di Rails e facendo anche un po’ di confronti.

Per quanto ne sappia, Discourse non legge alcun file Ruby diverso da plugin.rb. Legge invece i file JS e i file di configurazione. Tutti i file Ruby devono essere required in plugin.rb.

3 Mi Piace

Anch’io lo credo.

Carichi tutti i file Ruby aggiuntivi di cui avete bisogno direttamente da plugin.rb.

Ecco un esempio dal plugin Follow:

1 Mi Piace

È più o meno la mia impressione, dopo aver letto diversi plugin di Discourse su GitHub.

Sembra che Discourse legga solo plugin.rb e che dobbiamo caricare tutti gli altri file Ruby che potrebbero servire, come gli initializers, all’interno di plugin.rb.

Tuttavia, speravo di aver torto e che potesse esserci un’integrazione “più profonda” tra i plugin di Discourse e Rails; sono stato molto viziato da quanto sia ottimo Rails 6.

Grazie anche a te per la conferma.

1 Mi Piace

Penso che dovrebbe esserci un modo per richiedere codice di inizializzazione anche nel plugin.rb.
Hai provato questo nel plugin.rb

Rails.application.config.before_initialize do
  # il codice di inizializzazione va qui
end

Sì, non è un problema chiamare e caricare gli inizializzatori nel plugin.rb.

Il motivo della mia domanda è che sto attualmente scrivendo una piuttosto grande applicazione Rails 6 per un’azienda, convertendo i loro vecchi script per l’amministrazione interna (di diverse decadi) in un’app Rails. Per aggiungere gli inizializzatori, ho semplicemente una sottodirectory sotto config/initializers (in Rails) e tutti i miei file di inizializzazione vengono inclusi automaticamente, senza bisogno di scrivere alcun codice per includerli in Rails.

Grazie per tutte le vostre risposte. Molto apprezzate!

1 Mi Piace

Sì, mi piacerebbe molto che le funzionalità di Rails venissero portate nei plugin di Discourse. Una delle mie preferite sarebbe poter ricaricare in tempo reale i file Ruby senza dover riavviare il server.

1 Mi Piace

È proprio per questo che esiste reloadable_patch. Se avvolgi le modifiche alle classi Ruby in reloadable_patch, dovrebbero essere ricaricate in tempo reale!

1 Mi Piace

Posso avvolgere l’intero file plugin.rb al suo interno per lo sviluppo? Più seriamente, fino a che punto possiamo spingerci con questo?

Inoltre, aggiungere nuovi file o modificare qualsiasi file yml richiede un riavvio del server, giusto?

2 Mi Piace

Non dovresti dover eseguire un reloadable_patch per tutto. Molti dei metodi definiti in instance.rb per semplificare lo sviluppo dei plugin utilizzano internamente reloadable_patch, come ad esempio add_to_serializer.

Idealmente, la nostra API per i plugin è sufficientemente buona da non richiedere un’enorme quantità di interventi con reloadable_patch.

Sì, è vero. Mi chiedo se si possa fare qualcosa riguardo alle modifiche ai file yml; quella cosa mi infastidisce personalmente.

3 Mi Piace

È vero. Non sapevo che reloadable_patch fosse pensato per supportare il ricaricamento in tempo reale. Posso pensare a molti casi d’uso diversi da quelli in cui Discourse lo utilizza già. Ad esempio:

reloadable_patch do
 require 'x/y/z'
end

o patch di tipo monkey.

1 Mi Piace

Penso che rimuovere o aggiungere una funzione del genere rimarrebbe comunque problematico, dato che reloadable_patch viene chiamato all’interno della funzione.

In ogni caso, aiuta moltissimo.

1 Mi Piace

Ho iniziato a esaminare il ricaricamento in tempo reale delle modifiche YAML e in effetti funziona. I plugin potrebbero interrompere questo ricaricamento in tempo reale se non utilizzano correttamente reloadable_patch, ma una volta che tutti i tuoi plugin possono essere ricaricati in sicurezza, lo saranno anche le tue modifiche YAML.

4 Mi Piace

Sarebbe comunque super utile se potessi descrivere i passaggi esatti per utilizzare reloadable_patch.

Ecco cosa ho provato senza molto successo (sicuramente mi sta sfuggendo qualcosa):

after_initialize do
    add_to_serializer(:topic_view, :check, false) do
        puts 'nocheck'
    end
end

Una volta avviato il server, e dopo aver modificato nocheck in check, stampa ancora nocheck dopo aver ricaricato la rotta del topic.

after_initialize do
    reloadable_patch do |plugin|
        puts 'nocheck'
    end
end

Ancora senza successo quando ricarico qualsiasi pagina dopo aver modificato la stringa sotto puts.

Immagino di averti tratto in inganno nei post precedenti. reloadable_patch è utile per lo sviluppo di Discourse, ma @david ne ha spiegato molto bene l’utilizzo:


Qualsiasi cosa all’interno del blocco after_initialize di plugin.rb viene caricata solo durante l’avvio dell’applicazione e non nei successivi ricaricamenti.

Quindi, supponendo che tu voglia aggiungere qualcosa al serializzatore dell’utente. Il comportamento normale sarebbe:

All’avvio:

  • Discourse carica user_serializer.rb
  • Discourse carica plugin.rb, che contiene un override per user_serializer

Al ricaricamento:

  • Discourse ricarica user_serializer.rb
  • (la patch di plugin.rb non viene ricaricata, l’override del plugin viene perso)

Con il nostro sistema reloadable_patch:

All’avvio:

  • Discourse carica user_serializer.rb
  • Discourse carica plugin.rb e registra il reloadable_patch per il serializzatore dell’utente
  • Vengono eseguite le patch ricaricabili

Al ricaricamento:

  • Discourse ricarica user_serializer.rb
  • Vengono eseguite le patch ricaricabili
  • (evviva, l’override del plugin continua a funzionare)
6 Mi Piace

Questo descrive una proprietà fondamentale di Rails, che non è pertinente specificamente a Discourse.

In Rails, tutti gli initializers vengono caricati solo all’avvio di Rails, quindi qualsiasi plugin che esegue codice basato sull’initializer, come “after_initializer”, verrà eseguito solo all’avvio o al riavvio di Rails (correggetemi se sbaglio).

Il motivo per cui conosco questo aspetto è che sto attualmente sviluppando un’applicazione Rails per un cliente e ho scritto molti initializers per vari compiti (booleani, array statici, ecc.). In ogni caso, se modifichiamo il codice in un initializer di Rails, è necessario riavviare Rails (“Control c, rails s in dev”) per far sì che i nuovi valori negli initializers vengano caricati nell’app Rails.

Correggetemi se sbaglio! Grazie.

A volte, penso che possa essere un po’ confuso per alcuni sviluppatori di plugin di Discourse, specialmente per quelli che lavorano principalmente sui plugin di Discourse e non con le applicazioni Rails in generale, quando scriviamo “Discourse fa questo” o “Discourse fa quello”, quando in realtà stiamo descrivendo una funzione o proprietà fondamentale di Rails, non necessariamente pertinente a Discourse in sé.

Rails 6 legge tutti i file nella directory config/initializers (e in tutte le sottodirectory di config/initializers) solo all’avvio di Rails. Allo stesso modo (non sono al 100% sicuro riguardo ai plugin), un plugin di Discourse con codice dipendente da after_initialize verrà (confermatelo gentilmente) caricato dall’app Rails solo all’avvio o al riavvio di Rails, poiché questa è una proprietà fondamentale del processo di avvio di Rails.

Immagino che tutti quelli qui presenti che lavorano su Rails lo sappiano già. Io sto solo iniziando a conoscere questi dettagli (e sento di avere ancora molta strada da fare per diventare un esperto); perché sto lavorando quotidianamente su un’applicazione Rails (al momento), e per inciso, ora vorrei aver iniziato a lavorare con Rails un decennio fa, poiché provenendo da un background di sviluppo LAMP, trovo Rails molto migliore (facile e divertente da usare).

Quest’anno sono diventato un grande fan di Rails e sono molto grato a Discourse per avermi avviato su questo percorso.

Di nuovo, correggetemi se sbaglio! Grazie. Sto cercando di diventare più esperto in Rails.

6 Mi Piace

Esatto! È corretto, così come la tua comprensione degli initializer di Rails.

Anch’io sono un grande fan di Rails :slight_smile:

7 Mi Piace