Scopri Volt, un promettente framework Ruby per applicazioni dinamiche
Pubblicato: 2022-03-11Volt è un framework Ruby progettato per applicazioni ricche di dati. Sia il lato server che quello client sono scritti in Ruby (che viene poi compilato in JS usando OPAL), quindi questo permette allo sviluppatore di scrivere applicazioni molto dinamiche senza dover scrivere una singola riga di codice Javascript. Se sei un fan di Ruby come me, adorerai questo framework.
Nel tentativo di rendere le applicazioni web molto più dinamiche, i framework Javascript front-end come Angular.js, Backbone.js ed Ember.js hanno guadagnato molta popolarità. Tuttavia, questi framework spesso richiedono un'applicazione back-end per essere utili, quindi vengono utilizzati insieme a framework web come Ruby on Rails e Django.
D'altra parte, il framework di Ruby Volt è in grado di gestire il back-end e un front-end dinamico. Poiché entrambe le funzionalità sono strettamente integrate nel core (in effetti, Volt è più simile a un'architettura MVVM, sfruttando i vantaggi dei data binding), consente allo sviluppatore di creare rapidamente queste applicazioni.
Una caratteristica molto interessante che esce fuori dagli schemi è la funzione in tempo reale di Volt. Se hai mai realizzato applicazioni in tempo reale, sai che il processo può essere impegnativo: probabilmente hai implementato polling AJAX, socket Web, eventi inviati dal server (SSE) o persino utilizzato servizi esterni, aggiungendo complessità all'applicazione e persino sostenendo costi aggiuntivi . A differenza di altri framework, Volt mantiene attiva una connessione con il server (tramite socket Web), quindi invece di effettuare richieste Ajax per ogni azione, invia istantaneamente le modifiche a tutti i client. Non è necessaria alcuna configurazione per farlo funzionare.
Utilizzo di Volt per creare un'applicazione di chat
In questo tutorial sul framework Ruby ti guiderò attraverso il processo di creazione di un'applicazione in tempo reale utilizzando Volt e quale modo migliore di un'applicazione di chat per dimostrarne le capacità, dal momento che la chat rimane il caso d'uso numero uno delle applicazioni in tempo reale.
Prima di tutto, installiamo Volt e MongoDB. Quest'ultimo processo non sarà trattato in dettaglio:
gem install volt brew install mongodb
mkdir -p /data/db
(crea percorso db)
chown `id -u` /data/db (change the owner to have the proper dbpath permissions)
Ora siamo pronti per creare la nostra prima app, chiamiamola 'chat'. Possiamo farlo facilmente in un paio di righe:
volt new chat cd chat
La struttura del documento ha alcune somiglianze con Rails. La principale differenza che gli utenti di Rails noteranno è che abbiamo una cartella aggiuntiva all'interno dell'app che contiene il resto delle cartelle come risorse, controller, modelli e viste, questa cartella aggiuntiva è un "Componente".
Un componente è una sezione isolata dell'app. Tutte le pagine all'interno di un componente vengono renderizzate senza ricaricare la pagina poiché tutti i file per quel componente vengono caricati con la richiesta http iniziale, quindi se visitiamo una pagina di un componente diverso, verrà effettuata una nuova richiesta http e la pagina verrà 'ricaricata '. Per questo esempio utilizziamo il componente predefinito chiamato 'main'.
Avviamo il server eseguendo il comando 'volt server' nella console e vediamo come appare nel browser navigando su localhost:3000:
volt server
Inoltre, non dimenticare di avviare MongoDB nella console:
mongod
Possiamo notare che Volt viene fornito con un numero di pagine predefinite, tra cui "Home" e "Informazioni". Questi possono essere personalizzati subito.
L'altra cosa degna di nota è il pulsante di accesso nella parte in alto a destra della pagina. Volt ha una funzionalità "utente" integrata nel framework tramite la gemma "volt-user-templates", che fornisce un modo per registrare e autenticare gli utenti, fin da subito.
Iniziare
Ora iniziamo a lavorare sulla nostra app. Prima di tutto non abbiamo bisogno della pagina 'Informazioni', quindi possiamo andare avanti ed eliminare quanto segue: il file app/main/views/main/about.html
, l'azione about in app/main/controllers/main_controller.rb
, rimuovi il percorso /about
in app/main/config/routes.rb
e il collegamento di navigazione in app/main/views/main/main.html
.
<ul class="nav nav-pills pull-right"> <:nav href="/" text="Home" /> <:user-templates:menu /> </ul>
Ora mettiamoci al lavoro e iniziamo elencando tutti gli utenti registrati:
<:Body> <h1>Home</h1> <div class="row"> <div class="col-md-4"> {{ _users.each do |user| }} <div class="contact"> {{user._name}} </div> {{ end }} </div> </div>
Ora tutti gli utenti registrati vengono elencati nella home page. Nota che il codice scritto all'interno di {{ }} è codice Ruby che viene eseguito. In questo modo possiamo scorrere la raccolta degli utenti e stamparli tutti.
Come avrai notato, 'utenti' è il nome della raccolta in cui sono archiviati tutti gli utenti; qualcosa da tenere a mente è che si accede agli attributi con un carattere di sottolineatura ''
anteposto al nome dell'attributo. Affinché funzioni, dobbiamo prima aggiungere una riga di codice nella parte superiore del file main_controller.rb
:
model :store
Volt viene fornito con più modelli di raccolta accessibili dal controller e ognuno di essi memorizza le informazioni in un luogo diverso. Il modello di raccolta del negozio memorizza i dati nel datastore, e qui stiamo specificando il controller da utilizzare (in questo momento l'unico datastore supportato è MongoDB). Creiamo un paio di utenti per vedere come appare.
In questo momento non c'è niente di eccitante in questa pagina, stiamo solo elencando gli utenti registrati. Ora vorrei essere in grado di selezionare un utente a cui inviare un messaggio, rimuovere il nome dell'utente attualmente connesso dall'elenco (poiché non dovrebbe essere in grado di inviare messaggi a se stesso), mostrare l'elenco solo agli autenticati utenti e mostra una pagina di "destinazione" agli utenti non autenticati:
<:Body> <h1>Home</h1> {{ if Volt.user }} <div class="row"> <div class="col-md-4"> {{ _users.each do |user| }} {{ if user._id != Volt.user._id }} <div class="contact {{ if params._user_id == user._id }} active {{ end }}" e-click="select_conversation(user)"> {{user._name}} </div> {{ end }} {{ end }} </div> </div> {{ else }} <p>This is a sample application built with Volt to demonstrate its real-time capabilities. Please log in to access it.</p> {{ end }}
Volt.user restituisce l'utente corrente (loggato) o nullo.

L'attributo e-click ci consente di selezionare un metodo dal controller che verrà chiamato quando si fa clic su quell'elemento.
Attributi e CSS
In effetti, tutti gli attributi 'e-' sono raccoglitori di eventi in Volt, quindi ad esempio possiamo aggiungere e-submit a un modulo per scegliere l'azione che verrà chiamata sul controller. Aggiungeremo l'ID utente "selezionato" ai parametri in modo da poter sapere quale è stato selezionato e aggiungere una classe chiamata "attiva" che possiamo definire in seguito.
Ora creiamo il metodo select_conversation
nel controller:
def select_conversation(user) params._user_id = user._id end
E il gioco è fatto: se controlli di nuovo la pagina, puoi vedere che l'URL cambia ogni volta che fai clic sul nome di un utente. Inoltre, la classe 'active' viene aggiunta a quell'elemento, quindi aggiungiamo alcuni CSS per renderlo visibile (andrò avanti e aggiungerò il CSS per gli elementi che aggiungeremo in seguito):
.conversation{ form{ input{ margin: 10px 0 5px 0; } } }
.contact{ width:100%; padding:5px; margin: 4px 0; font-size:15px; cursor:pointer; &:hover{ background-color: #FAFAFA; } &.active{ background-color: #337ab7; color: #FFF; } .badge{ background-color: #900; } }
.message{ max-width: 80%; padding:10px 15px; margin: 5px 0; background-color: #FEFEFE; border: 1px solid #E7E7E7; border-radius: 5px; float: left; clear:both; &.sent{ background-color: #E4F3DB; border: 1px solid #B7D0A7; float: right; } p{ margin:0; } }
Ora creiamo un modulo sul lato destro per inviare messaggi a ciascun utente:
<:Body> <h1>Home</h1> {{ if Volt.user }} <div class="row"> <div class="col-md-4"> {{ _users.each do |user| }} {{ if user._id != Volt.user._id }} <div class="contact {{ if params._user_id == user._id }} active {{ end }}" e-click="select_conversation(user)"> {{user._name}} </div> {{ end }} {{ end }} </div> {{ if params._user_id }} <div class="col-md-8 well conversation"> {{ current_conversation.each do |message| }} <div class="message {{ if message._sender_id == Volt.user._id }} sent {{ end }}"> <p>{{ message._text }}</p> </div> {{ end }} {{ if current_conversation.count == 0 }} <p>You have no messages yet. Start chatting!</p> {{ else }} <div class="clearfix"></div> {{ end }} <form e-submit="send_message" role="form"> <div class="form-group"> <input class="form-control" type="text" placeholder="Write a message" value="{{ page._new_message }}" /> <button type="submit" class="btn btn-primary pull-right">Submit</button> </div> </form> </div> {{ end }} </div> {{ else }} <p>This is a sample application built with Volt to demonstrate its real-time capabilities. Please log in to access it.</p> {{ end }}
Per prima cosa, controlliamo se c'è un utente selezionato prima di visualizzare il modulo, quindi mostriamo tutti i messaggi della conversazione corrente (la conversazione con l'utente selezionato) da un metodo nel controller che definiremo tra un po', e in basso viene visualizzato un modulo per l'invio di nuovi messaggi.
Si noti che il valore dell'input è un attributo che stiamo creando nel modello di raccolta di pagine poiché non vogliamo che venga archiviato nell'archivio dati. Ora definiamo i metodi current_conversation
e send_message
nel controller:
def send_message unless page._new_message.strip.empty? _messages << { sender_id: Volt.user._id, receiver_id: params._user_id, text: page._new_message } page._new_message = '' end end def current_conversation _messages.find({ "$or" => [{ sender_id: Volt.user._id, receiver_id: params._user_id }, { sender_id: params._user_id, receiver_id: Volt.user._id }] }) end
Nel metodo send_message aggiungiamo un nuovo messaggio alla raccolta se il messaggio non è vuoto (stiamo controllando in linea in modo da non dover fare confusione con le convalide al momento), quindi impostiamo la pagina ._new_message to ''
così svuotiamo il campo di input.
Potremmo anche voler aggiungere quella riga alla fine del metodo select_conversation
. Il metodo di conversazione corrente interroga semplicemente la raccolta _messages
per i messaggi tra l'utente selezionato e l'utente corrente.
Concludi con le notifiche in tempo reale
Per finire, vorrei avere una sorta di sistema di notifica, in modo che gli utenti possano vedere quando altri utenti stanno inviando loro messaggi.
Aggiungiamo una nuova raccolta chiamata _notifications
e creiamone una nuova dopo che ogni messaggio è stato inviato:
def send_message unless page._new_message.strip.empty? _messages << { sender_id: Volt.user._id, receiver_id: params._user_id, text: page._new_message } _notifications << { sender_id: Volt.user._id, receiver_id: params._user_id } page._new_message = '' end end def select_conversation(user) params._user_id = user._id unread_notifications_from(user).then do |results| results.each do |notification| _notifications.delete(notification) end end page._new_message = '' end def unread_notifications_from(user) _notifications.find({ sender_id: user._id, receiver_id: Volt.user._id }) end
Inoltre, dobbiamo eliminare le notifiche dopo che un utente ha selezionato la conversazione e ha visto i nuovi messaggi, quindi ho aggiunto quella parte al metodo select_conversation
.
Aggiungiamo un contatore di notifiche proprio accanto al nome utente:
<div class="contact {{ if params._user_id == user._id }} active {{ end }}" e-click="select_conversation(user)"> {{user._name}} {{ if unread_notifications_from(user).count > 0 }} <span class="badge"> {{ unread_notifications_from(user).count }} </span> {{ end }} </div>
Ora l'app è pronta, puoi aprire un paio di browser e iniziare a testare le capacità in tempo reale di Volt.
Volt vale sicuramente la pena provare
Anche se il framework Volt non è maturo e robusto come la maggior parte dei popolari framework Ruby che esistono da anni (al momento Volt è ancora in versione beta), vale la pena considerare e studiare.
Se sei interessato, usa questo tutorial del framework Ruby per portare Volt a fare un giro. Tieni d'occhio gli ulteriori sviluppi, poiché Volt sembra un framework Ruby molto promettente anche in questa fase iniziale di sviluppo.
Ci sono molte nuove fantastiche funzionalità in cantiere e sono abbastanza sicuro che Volt diventerà più rilevante nei prossimi due anni, man mano che più persone inizieranno a sperimentarlo. A causa di una serie di funzionalità innovative, molti sviluppatori potrebbero innamorarsi di Volt e usarlo per il loro prossimo progetto Ruby.