Poznaj Volta, obiecującą platformę Ruby dla dynamicznych aplikacji
Opublikowany: 2022-03-11Volt to platforma Ruby zaprojektowana dla aplikacji bogatych w dane. Zarówno strona serwera, jak i klienta są napisane w języku Ruby (który jest następnie kompilowany do JS przy użyciu OPAL), dzięki czemu programista może pisać bardzo dynamiczne aplikacje bez konieczności pisania ani jednej linii kodu JavaScript. Jeśli jesteś fanem Ruby jak ja, pokochasz ten framework.
W celu uczynienia aplikacji internetowych dużo bardziej dynamicznymi, dużą popularność zyskały front-endowe frameworki Javascript, takie jak Angular.js, Backbone.js i Ember.js. Jednak te frameworki często wymagają aplikacji zaplecza, aby były użyteczne, więc są używane w połączeniu z frameworkami internetowymi, takimi jak Ruby on Rails i Django.
Z drugiej strony, Ruby framework Volt jest w stanie zarządzać back-endem i dynamicznym front-endem. Ponieważ obie funkcje są ściśle zintegrowane z jego rdzeniem (w rzeczywistości Volt bardziej przypomina architekturę MVVM, wykorzystującą zalety powiązań danych), umożliwia programiście szybkie tworzenie tych aplikacji.
Bardzo fajną funkcją, która wychodzi z pudełka, jest funkcja czasu rzeczywistego Volta. Jeśli kiedykolwiek tworzyłeś aplikacje czasu rzeczywistego, wiesz, że proces ten może być trudny – prawdopodobnie zaimplementowałeś AJAX-polling, web sockets, Server-Sent Events (SSE) lub nawet korzystałeś z usług zewnętrznych, zwiększając złożoność aplikacji, a nawet ponosząc dodatkowe koszty . W przeciwieństwie do innych frameworków, Volt utrzymuje aktywne połączenie z serwerem (za pośrednictwem gniazd sieciowych), więc zamiast wysyłać żądania Ajax dla każdej akcji, natychmiast przesyła zmiany do wszystkich klientów. Aby to zadziałało, nie jest wymagana żadna konfiguracja.
Używanie Volta do tworzenia aplikacji do czatu
W tym samouczku dotyczącym frameworka Ruby przeprowadzę Cię przez proces tworzenia aplikacji czasu rzeczywistego przy użyciu Volt i nie ma lepszego sposobu niż aplikacja do czatu, aby zademonstrować jej możliwości, ponieważ czat pozostaje numerem jeden w przypadku aplikacji czasu rzeczywistego.
Przede wszystkim zainstalujmy Volta i MongoDB. Ten ostatni proces nie zostanie szczegółowo omówiony:
gem install volt brew install mongodb
mkdir -p /data/db
(utwórz ścieżkę bazy danych)
chown `id -u` /data/db (change the owner to have the proper dbpath permissions)
Teraz jesteśmy gotowi do stworzenia naszej pierwszej aplikacji, nazwijmy ją „czat”. Możemy to łatwo zrobić w kilku linijkach:
volt new chat cd chat
Struktura dokumentu ma pewne podobieństwa do Rails. Główną różnicą, jaką zauważą użytkownicy Railsów, jest to, że mamy dodatkowy folder wewnątrz aplikacji, który zawiera pozostałe foldery, takie jak zasoby, kontrolery, modele i widoki. Ten dodatkowy folder to „Komponent”.
Component to wyizolowana sekcja aplikacji. Wszystkie strony wewnątrz komponentu są renderowane bez ponownego ładowania strony, ponieważ wszystkie pliki dla tego komponentu są ładowane z początkowym żądaniem http, więc jeśli odwiedzimy stronę innego komponentu, zostanie wykonane nowe żądanie http i strona zostanie „ponownie załadowana „. W tym przykładzie użyjmy domyślnego komponentu o nazwie „main”.
Uruchommy serwer, wykonując polecenie „volt server” w konsoli i zobaczmy, jak wygląda w przeglądarce, przechodząc do localhost:3000:
volt server
Nie zapomnij też uruchomić MongoDB w konsoli:
mongod
Możemy zauważyć, że Volt ma kilka domyślnych stron, w tym „Strona główna” i „Informacje”. Można je od razu dostosować.
Kolejną rzeczą, o której warto wspomnieć, jest przycisk logowania w prawym górnym rogu strony. Volt ma funkcję „użytkownika” zintegrowaną z ramą za pośrednictwem klejnotu „Vol-user-templates”, który umożliwia rejestrację i uwierzytelnianie użytkowników od razu po wyjęciu z pudełka.
Pierwsze kroki
Teraz zacznijmy pracować nad naszą aplikacją. Przede wszystkim nie potrzebujemy strony "O programie", więc możemy iść dalej i usunąć następujące elementy: Plik app/main/views/main/about.html
, akcja about w app/main/controllers/main_controller.rb
, usuń trasę /about
w app/main/config/routes.rb
i łącze nawigacyjne w app/main/views/main/main.html
.
<ul class="nav nav-pills pull-right"> <:nav href="/" text="Home" /> <:user-templates:menu /> </ul>
Przejdźmy teraz do rzeczy i zacznijmy od wylistowania wszystkich zarejestrowanych użytkowników:
<: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>
Teraz wszyscy zarejestrowani użytkownicy są wymienieni na stronie głównej. Zauważ, że kod zapisany wewnątrz {{ }} jest kodem Rubiego, który jest wykonywany. W ten sposób możemy iterować po kolekcji użytkownika i wydrukować każdy z nich.
Jak mogłeś zauważyć, „użytkownicy” to nazwa kolekcji, w której są przechowywani wszyscy użytkownicy; należy pamiętać, że dostęp do atrybutów uzyskuje się z podkreśleniem ''
przed nazwą atrybutu. Aby to zadziałało, najpierw musimy dodać wiersz kodu na górze pliku main_controller.rb
:
model :store
Volt jest wyposażony w wiele modeli kolekcji dostępnych z kontrolera, a każdy z nich przechowuje informacje w innym miejscu. Model gromadzenia danych przechowuje dane w magazynie danych, a tutaj określamy kontroler, który ma używać tego jednego (obecnie jedynym obsługiwanym magazynem danych jest MongoDB). Utwórzmy kilku użytkowników, aby zobaczyć, jak to wygląda.
W tej chwili nie ma nic ekscytującego na tej stronie, po prostu wymieniamy zarejestrowanych użytkowników. Teraz chciałbym mieć możliwość wybrania użytkownika do wysłania wiadomości, usunięcia nazwy aktualnie zalogowanego użytkownika z listy (ponieważ nie powinien on mieć możliwości wysyłania wiadomości do siebie), pokazania listy tylko uwierzytelnionym użytkowników i wyświetlaj stronę docelową nieuwierzytelnionym użytkownikom:
<: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 zwraca aktualnego (zalogowanego) użytkownika lub zero.

Atrybut e-click pozwala nam wybrać metodę z kontrolera, która zostanie wywołana po kliknięciu tego elementu.
Atrybuty i CSS
W rzeczywistości wszystkie atrybuty „e-” są powiązaniami zdarzeń w Volcie, więc na przykład możemy dodać e-submit do formularza, aby wybrać akcję, która zostanie wywołana na kontrolerze. Zamierzamy dodać identyfikator „wybranego” użytkownika do parametrów, abyśmy mogli wiedzieć, który z nich został wybrany i dodać klasę o nazwie „aktywny”, którą możemy później nadać stylowi.
Teraz stwórzmy metodę select_conversation
w kontrolerze:
def select_conversation(user) params._user_id = user._id end
I to wszystko – jeśli ponownie sprawdzisz stronę, zobaczysz, że adres URL zmienia się za każdym razem, gdy klikniesz nazwę użytkownika. Ponadto do tego elementu dodawana jest klasa 'active', więc dodajmy CSS, aby był widoczny (przejdę dalej i dodam CSS dla elementów, które dodamy później):
.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; } }
Teraz stwórzmy formularz po prawej stronie, aby wysyłać wiadomości do każdego użytkownika:
<: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 }}
Najpierw przed wyświetleniem formularza sprawdzamy, czy jest wybrany użytkownik, następnie wyświetlamy wszystkie komunikaty z bieżącej konwersacji (konwersacji z wybranym użytkownikiem) z metody w kontrolerze, który za chwilę zdefiniujemy, a na dole wyświetlamy formularz do wysyłania nowych wiadomości.
Zauważ, że wartość danych wejściowych jest atrybutem, który tworzymy w modelu zbierania stron, ponieważ nie chcemy, aby był przechowywany w magazynie danych. Teraz zdefiniujmy metody current_conversation
i send_message
w kontrolerze:
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
W metodzie send_message dodajemy nową wiadomość do kolekcji, jeśli wiadomość nie jest pusta (sprawdzamy inline, więc nie musimy w tej chwili zadzierać z walidacjami), a następnie ustawiamy stronę ._new_message to ''
tak opróżniamy pole wejściowe.
Możemy również chcieć dodać tę linię na końcu metody select_conversation
. Bieżąca metoda konwersacji po prostu wysyła zapytanie do kolekcji _messages
o wiadomości między wybranym użytkownikiem a bieżącym użytkownikiem.
Zakończ z powiadomieniami w czasie rzeczywistym
Na koniec chciałbym mieć jakiś system powiadomień, aby użytkownicy mogli zobaczyć, kiedy inni użytkownicy do nich wysyłają.
Dodajmy nową kolekcję o nazwie _notifications
i stwórzmy nową po wysłaniu każdej wiadomości:
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
Ponadto musimy usunąć powiadomienia po tym, jak użytkownik wybierze rozmowę i zobaczy nowe wiadomości, więc dodałem tę część do metody select_conversation
.
Dodajmy licznik powiadomień tuż obok nazwy użytkownika:
<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>
Teraz aplikacja jest gotowa, możesz otworzyć kilka przeglądarek i rozpocząć testowanie możliwości Volta w czasie rzeczywistym.
Volt jest zdecydowanie wart wypróbowania
Chociaż framework Volt nie jest tak dojrzały i solidny, jak większość popularnych frameworków Ruby, które istnieją od lat (w chwili Volt jest jeszcze w fazie beta), warto go rozważyć i przestudiować.
Jeśli jesteś zainteresowany, skorzystaj z tego samouczka dotyczącego frameworka Ruby, aby wziąć Volta na przejażdżkę. Miej oko na dalszy rozwój, ponieważ Volt wygląda jak bardzo obiecujący framework Ruby nawet na tym wczesnym etapie rozwoju.
W przygotowaniu jest wiele fajnych nowych funkcji i jestem prawie pewien, że Volt stanie się bardziej odpowiedni w ciągu najbliższych kilku lat, ponieważ coraz więcej ludzi zacznie z nimi eksperymentować. Ze względu na szereg innowacyjnych funkcji, wielu programistów może zakochać się w Volcie i wykorzystać go w swoim następnym projekcie Ruby.