Implementing ‘Load More’ with Stimulus and Importmap in Ruby on Rails 7

Rahul kumar
Simform Engineering
5 min readSep 25, 2023

Learn how to create a “Load more” button for seamless data retrieval without page refreshing.

Ruby on Rails introduces powerful features like Importmap for streamlined JavaScript management and embraces Stimulus. In this blog post, we will delve into the details of these features and leverage them to implement a ‘Load More’ feature.

First, let’s understand the basic concepts:

What is Ruby on Rails?

Ruby on Rails is a web application framework written in the Ruby language. It follows the Model-View-Controller (MVC) architecture pattern and provides a standardized way to develop web applications with built-in conventions and tools.

What is Importmap?

Importmap is a tool that allows you to manage JavaScript dependencies in your web application. It simplifies the process of loading JavaScript modules by creating a central map that lists all the required modules and their dependencies.

What is Stimulus?

Stimulus is a JavaScript framework designed to enhance the user interface of web applications. It provides a lightweight and modular approach to adding interactivity to your web pages without requiring a full single-page application (SPA) architecture. With Stimulus, you can create reusable JavaScript controllers that modify HTML elements on a page in response to user interactions.

Implementing `Load more` with Stimulus in Rails 7 application

To integrate “Load More” into your Ruby on Rails application, you will need:

  • Rails ~> 7.0.4
  • Ruby ~> 3.1.0

Before starting the implementation, ensure you have — basic knowledge of HTML, JavaScript, Stimulus & Importmap.

Let’s start!

Step 1: Add the necessary gem

Add the ‘requestjs-rails’ gem to your Gemfile within the appropriate section:

gem 'requestjs-rails'

Run the following command to install the gem:

bundle install

Step 2: Create the Stimulus Controller

To create a Stimulus controller to handle the “Load More” functionality, create a file named user_profile_controller.js and place it in your javascript/controllers directory.

Run the following command to generate the Stimulus controller:

rails generate stimulus UserProfile

This command will generate a Stimulus controller file named user_profile_controller.js in the app/javascript/controllers directory.

// app/javascript/controllers/user_profile_controller.js

import { Controller } from "@hotwired/stimulus"
import { get } from '@rails/request.js'

export default class extends Controller {
connect() {
this.loadMore()
}

loadMore()
{
let count = this.element.dataset.counter
count = parseInt(count) + 9
this.element.dataset.counter = count
get(`/?limitCount=${count}`, { responseKind: "turbo-stream"} )
}
}

In the above Stimulus controller:

  • The line we’re talking about is the one that starts with export default class extends Controller. This line exports a class that extends the Controller class from Stimulus. It defines a Stimulus controller responsible for managing the “Load More” functionality.
  • The connect method is called when the controller connects with the DOM, triggering loadMore.
  • Within the connect method, we call the loadMore function. This ensures that when the controller is connected to the DOM, it immediately triggers the loadMore function to either load initial data or set up event listeners, depending on the context.
  • We retrieve the current counter value from the element’s dataset.
  • We increment the count by 9 to load additional data. If you wish to specify a different increment value for loading more data, you can modify the code accordingly.
  • We update the dataset with the new count value.
  • Finally, we make an AJAX GET request with the updated count parameter, anticipating a Turbo Stream response.

Step 3: Configure Model

You can utilize the “user_profiles” model for your application or adapt it to suit your specific needs.

Run the following command to generate the user_profiles model:

rails generate model UserProfile name:string age:integer phone_number:string city:string address:text

After generating the model, run the migration to create the database table:

rails db:migrate
class CreateUserProfiles < ActiveRecord::Migration[7.0]
def change
create_table :user_profiles do |t|
t.string :name
t.integer :age
t.string :phone_number
t.string :city
t.text :address
t.timestamps
end
end
end

Step 4: Update the Rails Controller and View

In this step, configure your Rails app for the “Load More” feature by creating the UserProfiles Controller to handle user data and designing the index.html.erb view for displaying user-profiles and the “Load More” button.

In this Rails controller action:

  • We have a Ruby on Rails controller named UserProfilesController.
  • It contains an index action, which is responsible for handling requests to view user profiles.
  • Within the index action, it retrieves user profiles from the database using ActiveRecord methods. It limits the number of records fetched using limit and skips the first 9 records using offset. The limitCount parameter is expected to be passed in the request, allowing dynamic loading of user profiles.
# app/controllers/user_profiles_controller.rb

class UserProfilesController < ApplicationController
def index
@user_profiles = UserProfile.limit(params[:limitCount]).offset(9)
end
end

In the Rails view template below:

In below index.html.erb view file, the HTML code establishes the framework for a page that displays a list of user-profiles and offers a “Load More” button. This button, powered by a Stimulus controller named “user-profile” and the “loadMore” data action, dynamically loads additional user profiles.

<!-- app/views/user_profiles/index.html.erb -->

<h1 class="my-5">List of all user</h1>
<div data-controller="user-profile" data-counter="0">
<div id="loadUserData">
</div>
<div class="d-flex justify-content-center mt-4">
<button type="button" data-action="click->user-profile#loadMore" class="btn btn-danger">Load More</button>
</div>
</div>

Step 5: Create a Partial View

Create a partial view to render individual user profiles. For example, create a file named ‘_user_profile.html.erb’:

The below code creates a Turbo Stream block to manage dynamic user profile updates. When you load more profiles, the Stimulus controller fetches them from the server, and Turbo Streams seamlessly adds them to the page, all without the need for refreshing.

<!-- app/views/user_profiles/index.turbo_stream.erb -->

<%= turbo_stream.update "loadUserData" do %>
<div class="row row-cols-1 row-cols-md-3 g-4">
<% @user_profiles.each do |user| %>
<div class="col">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title"><%= user.name %></h5>
<p class="card-text">Age: <%= user.age %></p>
<p class="card-text">Phone Number: <%= user.phone_number %></p>
<p class="card-text">City: <%= user.city %></p>
<p class="card-text">Address: <%= user.address %></p>
<%= link_to "View Profile", user_profile_path(user), class: "btn btn-primary" %>
</div>
</div>
</div>
<% end %>
</div>
<% end %>

Step 6: Update Your Routes

Update your routes to handle the AJAX request:

Rails.application.routes.draw do
resources :user_profiles
root to: 'user_profiles#index'
end

Conclusion

By combining Stimulus and Importmap in Ruby on Rails 7, you can create a clean and efficient ‘Load More’ feature for your web applications. Importmap simplifies JavaScript dependency management, and Stimulus provides an elegant way to handle user interactions and dynamic behavior.

Stay tuned for more insights on Ruby on Rails 7 in future posts.

Meanwhile, subscribe to the Simform Engineering blog for more web development tips and tutorials.

Follow Us: Twitter | LinkedIn

--

--