Molti plugin includono molte definizioni di classi all’interno di plugin.rb o utilizzano require_relative per caricare file ruby. Questo funziona, ma presenta alcuni svantaggi:
- Nessun ricaricamento automatico delle modifiche durante lo sviluppo. Qualsiasi modifica richiede un riavvio completo del server
- Mettere le chiamate
requirenell’ordine corretto può essere difficile - Se vengono caricati (
require’d) al di fuori del bloccoafter_initialize, altre classi/moduli caricati automaticamente potrebbero non essere disponibili
C’è una soluzione! I plugin possono fare affidamento sul sistema di caricamento automatico standard di Rails. Per i nuovi plugin, tutto ciò di cui hai bisogno è definito nello scheletro del plugin. Questo argomento descrive come adattare un plugin esistente ed estendere la configurazione.
1. Definire un modulo e un Rails::Engine per il tuo plugin
In plugin.rb, definisci un modulo per il tuo plugin con un PLUGIN_NAME univoco e aggiungi una riga require_relative per caricare il file del motore che stiamo per creare.
# name: my-plugin-name
# ...
module ::MyPluginModule
PLUGIN_NAME = "my-plugin-name"
end
require_relative "lib/my_plugin_module/engine"
Ora crea {plugin}/lib/my_plugin_module/engine.rb:
module ::MyPluginModule
class Engine < ::Rails::Engine
engine_name PLUGIN_NAME
isolate_namespace MyPluginModule
end
end
Cose importanti da notare:
-
In
plugin.rb, devi includere::prima del nome del tuo modulo per definirlo nello spazio dei nomi principale (altrimenti, verrebbe definito sottoPlugin::Instance) -
require_relative "lib/.../engine"deve trovarsi nella radice del fileplugin.rb, non all’interno di un bloccoafter_initialize -
Mettere il motore nel proprio file sotto
lib/è importante. Definiscerlo direttamente nel fileplugin.rbnon funzionerà. (Rails utilizza la presenza di una directorylib/per determinare la radice del motore) -
Il percorso del file deve includere il nome del modulo, secondo le regole di Zeitwerk
-
L’
engine_nameviene utilizzato come prefisso per le attività rake e qualsiasi route definita dal motore (
docs di rails) -
isolate_namespaceaiuta a prevenire la fuoriuscita di elementi tra il core e il plugin (
docs di Rails)
2. Definire file ruby nella corretta struttura di directory
Il motore ora caricherà automaticamente tutti i file in {plugin}/app/{type}/*. Ad esempio, possiamo definire un controller
{plugin}/app/controllers/my_plugin_module/examples_controller.rb
module ::MyPluginModule
class ExamplesController < ::ApplicationController
requires_plugin PLUGIN_NAME
def index
render json: { hello: "world" }
end
end
end
Questo verrà ora caricato automaticamente ogni volta che qualcosa in Rails tenta di accedere a ::MyPluginModule::MyController. Per testare le cose, prova ad accedere a quella classe dalla console rails.
Affinché il caricamento automatico funzioni correttamente, i percorsi dei file devono corrispondere alla gerarchia completa del modulo/classe secondo le regole definite da Zeitwerk.
3. Definire le route sul motore del plugin
Crea un file {plugin}/config/routes.rb
MyPluginModule::Engine.routes.draw do
get "/examples" => "examples#index"
# definisci le route qui
end
Discourse::Application.routes.draw do
mount ::MyPluginModule::Engine, at: "my-plugin"
end
Questo file verrà caricato automaticamente dal motore e le modifiche avranno effetto senza riavviare il server. In questo caso, l’azione del controller sarebbe disponibile su /my-plugin/examples.json.
4. Aggiungere più percorsi caricabili automaticamente
A volte potresti voler introdurre directory aggiuntive di file Ruby caricabili automaticamente. L’esempio più comune è la directory lib/ in un plugin.
Modifica la definizione del motore per aggiungere lib/ ai percorsi di caricamento automatico del motore:
class Engine < ::Rails::Engine
engine_name PLUGIN_NAME
isolate_namespace MyPluginModule
config.autoload_paths << File.join(config.root, "lib")
end
Ora puoi definire un modulo lib come
{plugin}/lib/my_plugin_module/some_lib_module.rb
module ::MyPluginModule::SomeLibModule
end
E ora qualsiasi riferimento a ::MyPluginModule::SomeLibModule caricherà automaticamente il modulo da questo file.
5. Profitto!
Tutti questi file verranno ora caricati automaticamente senza alcuna chiamata require deliberata. Le modifiche verranno rilevate automaticamente da rails e ricaricate sul posto senza riavvio del server.
Questo documento è controllato in versione - suggerisci modifiche su github.