VOOZH about

URL: https://thenewstack.io/turbocharging-ruby-on-rails-with-html-over-the-wire/

⇱ Turbocharging Ruby on Rails with 'HTML Over the Wire' - The New Stack


TNS
SUBSCRIBE
Join our community of software engineering leaders and aspirational developers. Always stay in-the-know by getting the most important news and exclusive content delivered fresh to your inbox to learn more about at-scale software development.
REQUIRED
It seems that you've previously unsubscribed from our newsletter in the past. Click the button below to open the re-subscribe form in a new tab. When you're done, simply close that tab and continue with this form to complete your subscription.
The New Stack does not sell your information or share it with unaffiliated third parties. By continuing, you agree to our Terms of Use and Privacy Policy.
Welcome and thank you for joining The New Stack community!
Please answer a few simple questions to help us deliver the news and resources you are interested in.
REQUIRED
REQUIRED
REQUIRED
REQUIRED
REQUIRED
Great to meet you!
Tell us a bit about your job so we can cover the topics you find most relevant.
REQUIRED
REQUIRED
REQUIRED
REQUIRED
REQUIRED
Welcome!

We’re so glad you’re here. You can expect all the best TNS content to arrive Monday through Friday to keep you on top of the news and at the top of your game.

What’s next?

Check your inbox for a confirmation email where you can adjust your preferences and even join additional groups.

Follow TNS on your favorite social media networks.

Become a TNS follower on LinkedIn.

Check out the latest featured and trending stories while you wait for your first TNS newsletter.

PREV
1 of 2
NEXT
VOXPOP
As a JavaScript developer, what non-React tools do you use most often?
Angular
0%
Astro
0%
Svelte
0%
Vue.js
0%
Other
0%
I only use React
0%
I don't use JavaScript
0%
Thanks for your opinion! Subscribe below to get the final results, published exclusively in our TNS Update newsletter:
NEW! Try Stackie AI
From clobbered drafts to real-time sync
Apr 14th 2026 10:00am, by David Moore
TypeScript 6.0 RC arrives as a bridge to a faster future
Mar 14th 2026 9:00am, by Darryl K. Taft
Mastra empowers web devs to build AI agents in TypeScript
Jan 28th 2026 11:00am, by Loraine Lawson
2022-07-23 05:00:47
Turbocharging Ruby on Rails with 'HTML Over the Wire'
Frontend Development / Software Development

Turbocharging Ruby on Rails with ‘HTML Over the Wire’

Tutorial showing how to use the modern HTML Over the Wire — and Hotwire specifically — approach with the classic Ruby on Rails framework.
Jul 23rd, 2022 5:00am by David Eastman
👁 Featued image for: Turbocharging Ruby on Rails with ‘HTML Over the Wire’
Lead image via Shutterstock.
Ruby was my first love, my first language was C, and now I go steady with C#. This is a typical romantic journey for most developers; falling for a shiny new methodology, only to flirt with a statically typed language later. But there’s one thing I have been consistent with: I don’t want to write JavaScript if I don’t have to. Now, as a pragmatic developer, I recognize why I might need JavaScript, but I’d always prefer to be in the more comfortable confines of a bigger language. Since the birth of node.js, there have been plenty of devs who are happy to use JavaScript exclusively — for both client and server. And admittedly, I did like the control that media queries gave me with responsive web design. I’ve always thought Ruby on Rails was a little easier to manage because it was “opinionated” — even if it was a little too keen to push you into a database. So I was intrigued by the idea of “HTML Over the Wire”; and Hotwire specifically. It seems to give you JavaScript-like abilities without actually having to write any. So I thought it might be time to fire up a Rails project and see how that went.

Installing Rails (Again)

So, let’s start with a simple Rails installation. We just want a form and response. I’ll assume that you are comfortable with what Rails is and its basic tenets, but maybe (like me) you haven’t done all this stuff for a while. So here’s what I’ll do:
  • I won’t use a database;
  • I’ll try using a generator, so I don’t have to remember all the files needed.
I have an rvm (Ruby enVironment Management), so let’s try to install a new ruby to match what we need for Rails. Naturally, whatever Ruby I did have wasn’t high enough:
<code class="language-bash">theNewStack> rvm get stable
...
theNewStack> rvm use ruby --install --default
...
theNewStack> ruby --version
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin21]</code>
Then the important stuff:
<code class="language-bash">theNewStack> gem install rails</code>
That gave me 35 gems and documentation.
<code class="language-bash">theNewStack> rails --version
Rails 7.0.3</code>
Ok, so let’s ask the generator for a skeleton application, with no tests or active record.
<code class="language-bash">theNewStack> rails new SimpleApp --skip-active-record --no-test-framework</code>
At least we have enough to throw something immediately on the screen. As I demonstrated with Sinatra, the current favored server is called Puma. So on my Mac, we can wander into the app directory and start a server with Puma:
<code class="language-bash">cd SimpleApp 
bin/rails server</code>
And at http://localhost:3000 we see the default Rails page. I can already see some Hotwire things in the Gemfile (there is a “turbo-rails” gem), so perhaps we don’t need to do anything further for that. We want a simple form, like a sign-up page, and then update it after submission. I used to use a Flash Message for this in the past. So in a Model/View/Controller world, we want a user model, then a form for our “new user” view, and finally a registrations controller. No, I haven’t written any of these things yet. Fortunately, despite not using Rails recently, my old friend the “routes.rb” file still exists. A route is how we describe our internal architecture in good REST fashion. So I associate the URL GET request “/sign_up” with a new registration, and it’s POST response appropriately too.
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

Rails.application.routes.draw do
 get "sign_up", to: "registrations#new"
 post "sign_up", to: "registrations#create"
end
OK, so we better make a registrations_controller. Remember, the Rails world is very opinionated, so stick to the mantra and use the words and phrases as expected. We are already being difficult by not having a database! But first, a quick User model. Note that because I ditched the database, we are using ActiveModel to persuade Rails we are good citizens. So in “app/models/user.rb” we have:
class User
 include ActiveModel::Validations
 include ActiveModel::Conversion
 extend ActiveModel::Naming

 attr_accessor :objectId, :name, :email, :password

 @id = nil

 def initialize(attributes = {})
 @name = attributes[:name]
 @email = attributes[:email]
 @password = attributes[:password]
 @objectId = attributes[:id]
 end

 def id
 return self.objectId
 end

 def persisted?
 !(self.id.nil?)
 end
end
And a quick RegistrationsController in “app/controllers/registrations_controller.rb”:
class RegistrationsController < ApplicationController
 def new
 @user = User.new
 end
end
And this minimal view in “app/views/registrations/new.erb.html”
<code class="language-html"><h1>Sign Up</h1></code>
We get this blessed result in the browser: 👁 Image
OK, that is cool but we need a more fulsome form. After all we need something for Hotwire to do. Now, this isn’t a post about the multitude of ways you can get a screen to look nice, but I’ve squeezed a bit of juice out of Rails and HTML, so the form looks alright without having to do anything much in CSS. For a real project, you would probably want to do the opposite. The Rails smart magic works via “form_for”, between the ERB tags, which looks at the model (i.e. user.rb) and riffs on that. It even deduces that “Create User” would be a good default for the submit button text. This is what you are paying for when using Rails. Here is the nicer view:
<code class="language-html"><h1>Sign Up</h1>

<%= form_for (@user), url: sign_up_path do |form| %>
 <div >
 <%= form.label :name %>
 <%= form.text_field :name, class: "form_field", id: "name_field", placeholder: "The New Stack" %>
 </div>
 <br>
 <div>
 <%= form.label :email %>
 <%= form.text_field :email, class: "form_field", id: "email_field", placeholder: "info@thenewstack.io" %>
 </div>
 <br>
 <div>
 <%= form.label :password %>
 <%= form.password_field :password, class: "form_field", id: "password_field", placeholder: "password123"%>
 </div>
 <br>
 <div>
 <%= form.submit %>
 </div>
<% end %></code>
Note the URL override to send the response to the sign_up path we have made in routes. I’ve identified the fields, as will need that shortly. The rest is just Rails and HTML. Just to make it a little cleaner, I have added a simplistic CSS in “app/assets/stylesheets/application.css”:
.form_field
{
 display : block; 
 min-width: 30%;
}
This all gives us this: 👁 Image

Getting Hotwire Involved

OK, wonderful, but this post is about Hotwire. Normally we would have to redraw a new page here, or use a little Flash Message to somehow confirm that a user has been created. But what Hotwire in its Turbo Stream mode gives us is a chance to replace a section of code in response to an action. This is done in AJAX so no screen drawing is needed, but also it is done in a nice Railsy way. A Railsway. Take a look at “app/views/registrations/submit.turbo_stream.erb”:
<code class="language-ruby"><%= turbo_stream.replace("name_field") do %>
 <span class = "form_field" style="font-weight: bold"><%=@user.name%>
<% end %>

<%= turbo_stream.replace("email_field") do %>
 <span class = "form_field" style="font-weight: bold"><%=@user.email%>
<% end %>

<%= turbo_stream.replace("password_field") do %>
 <span class = "form_field" style="font-weight: bold">Password recorded 
<% end %></code>
Firstly, note the nomenclature of the filename. The rest is kind of simple; in this case we replace the identified div with some simple HTML. I added the create method to the “app/controllers/registrations_controller.rb”:
class RegistrationsController < ApplicationController
 attr_accessor :user

 def new
 @user=User.new
 end

 def create
 @user = User.new(params.require(:user))
 render "submit"
 end
end
I clearly haven’t quite got the variable use right here: the @user in the create that reads the incoming parameters is the important thing though. Here is the page after you create a user: 👁 Image
So, to summarise the behavior and flow:
  1. We relate the GET request sign_up page to the registration controller’s new method in “routes.rb”.
  2. Rails knows to relate the registrations new method to the correct registrations view “new.html.erb”, where the form is.
  3. The form is displayed, based on the “user.rb” model.
  4. The button on the form sends a POST request to sign_up.
  5. We related the POST sign_up to the controller’s create method. This directs rails to render the submit view.
  6. Turbo looks for the “submit.turbo_stream.erb”, and makes the replacements asked for.
  7. The result is no page redrawing.
While I took a bit of time to grok how Rails is currently set up, and I almost certainly haven’t used it in the official way, it is still very easy to play around and see the results. However, familiarity with HTML and CSS are still necessary — even if we can briefly ignore our JavaScript overlords.
TRENDING STORIES
David has been a London-based professional software developer with Oracle Corp. and British Telecom, and a consultant helping teams work in a more agile fashion. He wrote a book on UI design and has been writing technical articles ever since....
Read more from David Eastman
SHARE THIS STORY
TRENDING STORIES
SHARE THIS STORY
TRENDING STORIES
TNS DAILY NEWSLETTER Receive a free roundup of the most recent TNS articles in your inbox each day.
The New Stack does not sell your information or share it with unaffiliated third parties. By continuing, you agree to our Terms of Use and Privacy Policy.