Rails 6.1 - Hotwire with Lazy Loading

A simple Rails App that works off one page using flash messages

Overview

As was seen in Using Hotwire with Flash Messages Hotwire can easily load data - let’s do this in a lazy loaded way (after the html is loaded we add data).

Basic Setup

Start with the code at the end of: Using Hotwire in Rails

Prepare our code

Let’s remove the extra Tweet.new load in the controller’s index method:

# app/controllers/tweets_controller.rb
  def index
    @tweets = Tweet.all.order(created_at: :desc)
    # @tweet = Tweet.new # no longer needed
  end

now if we try our code we get a null value error (for course).

So to fix this we need to load the data back in (and restructure our index page a bit).

Turbo works well if you use the normal templates - so in this case we will use the new template on the home page to call the new form and get its own data:

# app/views/tweets/index.html.erb
<h1>Tweets</h1>
<%= turbo_stream_from "tweets" %>

<h2 class="mt-3 h4 text-muted">New Tweet</h2>
<div class="card card-body">
  <%= turbo_frame_tag "new-tweet", src: new_tweet_path, target: "_top" %>
</div>

<h2 class="mt-3 h4 text-muted">Tweet Feed</h2>
<%= turbo_frame_tag "tweets" do %>
  <%= render @tweets %>
<% end %>

Notice the new template is using the dom_id “new-tweet” and not “new_tweet”. Also note that this tag has a src: - that is where it is getting its data source (& view to use) - in this case the new_tweet_path routes to tweets_controller#new and that calls the veiw template. The final thing to note is the target - this tells the turbo_tag to look / act outside the contraints of its frame (otherwise we couldn’t reach the controller).

Currently this won’t work yet - we need to create a matching tag – including the target in the new template. So our updated new template now looks like:

 app/views/tweets/new.html.erb
<h1>New Tweet</h1>

<%= turbo_frame_tag "new-tweet", target: "_top" do %>
  <%= render 'form', tweet: @tweet %>
<% end %>

Now we should have a new form that uses the standard rails data flow within the index - just like the display and edit of individual tweets also uses show and edit templates too.

Resources

The repo where you can find this code in the branch: https://github.com/btihen/ruby_kafi_hotwire_tweets/commits/hotwire_lazy_load_data

Bill Tihen
Bill Tihen
Developer, Data Enthusiast, Educator and Nature’s Friend

very curious – known to explore knownledge and nature