Nel tempo Discourse è diventato più complesso e può risultare scoraggiante per i principianti capire come i dati viaggino dall’applicazione back-end Ruby on Rails fino all’applicazione Ember.js in front-end.
Questo tutorial è pensato per mostrare il ciclo di vita completo di una richiesta in Discourse e spiegare i passaggi necessari se si desidera creare una nuova pagina con il proprio URL nella nostra applicazione.
Prima gli URL
Preferisco sempre iniziare a pensare alle funzionalità in termini di URL per accedervi. Ad esempio, supponiamo di voler creare una funzionalità di amministrazione che mostrasse l’ultimo snack che ho mangiato mentre lavoravo su Discourse. Un URL adatto sarebbe /admin/snack
In questo caso:
-
Visitando
/admin/snacknel browser, lo snack dovrebbe essere visualizzato utilizzando la “full stack”, in altre parole l’applicazione Ember verrà caricata e richiederà i dati necessari per visualizzare lo snack. -
Visitando
/admin/snack.jsondovrebbe essere restituiti i dati JSON dello snack stesso.
Il lato server (Ruby on Rails)
Iniziamo creando un nuovo controller per lo snack.
app/controllers/admin/snack_controller.rb
class Admin::SnackController < Admin::AdminController
def index
render json: { name: "donut", description: "delicious!" }
end
end
In questo caso ereditiamo da Admin::AdminController per ottenere tutti i controlli di sicurezza che garantiscono che l’utente che visualizza il controller sia un amministratore. C’è solo un’altra cosa da fare prima di poter accedere al nostro controller, ed è aggiungere una riga a config/routes.rb:
Trova il blocco che sembra questo:
namespace :admin, constraints: StaffConstraint.new do
# lots of stuff
end
E aggiungi questa riga al suo interno:
get 'snack' => 'snack#index'
Una volta fatto, dovresti essere in grado di visitare /admin/snack.json nel browser e vedrai i JSON dello snack! La nostra API dello snack sembra funzionare ![]()
Naturalmente, mentre si sviluppa la propria funzionalità aggiungendo complessità, probabilmente non ci si limiterebbe a restituire JSON hardcoded da un controller come questo, ma si interrogherebbe il database e lo si restituirebbe in quel modo.
Il lato client (Ember.js)
Se si apre il browser e si visita /admin/snack (senza il .json), si vedrà che Discourse dice “Oops! That page doesn’t exist.” — questo perché non c’è nulla nella nostra applicazione front-end Ember per rispondere alla rotta. Aggiungiamo un template .gjs per mostrare il nostro snack:
frontend/discourse/admin/templates/snack.gjs
<template>
<h1>{{@controller.model.name}}</h1>
<hr />
<p>{{@controller.model.description}}</p>
</template>
E, come sul lato API di Rails, dobbiamo configurare la rotta. Apri il file frontend/discourse/admin/routes/admin-route-map.js e cerca il metodo export default function(). Aggiungi la seguente riga:
this.route("snack");
C’è un’ultima cosa da fare nel mondo Ember, ed è far sì che l’applicazione Ember esegua una richiesta AJAX per recuperare i nostri JSON dal server. Creiamo un ultimo file. Sarà un Ember Route. La sua funzione model() verrà chiamata quando la rotta viene inserita, quindi faremo la nostra chiamata ajax lì dentro:
frontend/discourse/admin/routes/admin-snack.js
import { ajax } from "discourse/lib/ajax";
import DiscourseRoute from "discourse/routes/discourse";
export default class AdminSnackRoute extends DiscourseRoute {
model() {
return ajax("/admin/snack.json");
}
}
Ora, puoi aprire il browser a /admin/snack e dovresti vedere i dettagli dello snack renderizzati nella pagina!
Riepilogo
-
Aprendo il browser a
/admin/snacksi avvia l’applicazione Ember -
Il router dell’applicazione Ember dice che
snackdovrebbe essere la rotta -
La rotta Ember per
snackfa una richiesta AJAX a/admin/snack.json -
Il router dell’applicazione Rails dice che dovrebbe essere il
admin_snack controller -
Il
admin_snack_controllerrestituisce JSON -
L’applicazione Ember ottiene i JSON e renderizza il template
.gjs
Dove andare da qui
Ho scritto un tutorial di follow-up su come aggiungere un Componente Ember a Discourse.
Questo documento è versionato - suggerisci modifiche su github.