Creating A Rails 7 App: With esbuild, bootstrap and jquery

Techie     April 2022

Introduction

Creating a Rails project is as simple as running one line of command on the terminal. While it’s easy to do so, it’s imperative to configure the basic tools for the project. This section outlines the necessary steps for creating and configuring a new Rails 7 project. We will use esbuild for JavaScript bundling, bootstrap for CSS and JQuery for JavaScript and SQLite as the database.


Prerequisites


Creating the project

1 . Open the terminal, cd into your projects directory and run this command:

$ rails new my_app -j esbuild --css bootstrap

The -j directive is used to define the JavaScript bundler while the - -css directive defines the CSS library.

If you don’t want to use the default SQLite database, you can specify a different database with the -d directive like so:

$ rails new my_app -j esbuild --css bootstrap -d mysql


Even after the command has created the project, it is possible to switch databases like so, in root of the project:

$ rails db:system:change --to=postgresql 


NB: The bootstrap version installed will be the latest version.


2 . cd into my_app and add jquery, jquery-ujs and jquery-ui

$ yarn add jquery jquery-ujs jquery-ui


3 . Import jquery, jquery-ujs and jquery-ui in app/javascript/application.js

Normally, this is how we would import them.

// app/javascript/application.js
// ...

import jquery from 'jquery';
window.jQuery = jquery;
window.$ = jquery;
import "jquery-ui"

But since JavaScript imports are hoisted; i.e. all imports are loaded before any other code regardless of the order, it causes a problem because JavaScript will try to load jquery-ui before jquery is made available to the window. Let’s fix that:

i). In app/javascript, create src sub-directory and in it create jquery.js file:

$ mkdir -p app/javascript/src; touch app/javascript/src/jquery.js


Add this to it:

// app/javascript/src/jquery.js

import jquery from 'jquery';
window.jQuery = jquery;
window.$ = jquery;


ii). In app/javascript/application.js add this:

// app/javascript/application.js
// ...

import "./src/jquery"
import "jquery-ui"
import "jquery-ujs"


4 . Set up notifications

i). Add notifications in app/views/layouts/application.html.erb

<!-- views/layouts/application.html.erb -->
<!-- .... -->  
  <body>
   <% flash.each do |key, value| %>
    <div class="<%= flash_class(key) %>">
     <%= value %>
    </div>
   <% end %>
    <%= yield %>
  </body>


ii). Create the flash_class method in app/helpers/application_helper.rb

# app/helpers/application_helper.rb
# ...

  def flash_class(level)
    case level
      when :notice then "alert alert-info"
      when :success then "alert alert-success"
      when :error then "alert alert-danger"
      when :alert then "alert alert-danger"
    end
  end


5 . Create a navbar in app/views/layouts/application.html.erb

<!-- views/layouts/application.html.erb -->
<!-- .... -->  

  <body>

   <nav class="navbar navbar-expand-sm bg-dark navbar-dark fixed-top">
    <div class="container-fluid">
     <a class="navbar-brand" href="#">Rails 7 Bootstrap</a>
     <a class="navbar-brand" href="#">Jquery</a>
    </div>
   </nav>
  
   <% flash.each do |key, value| %>
    <div class="<%= flash_class(key) %>">
     <%= value %>
    </div>
   <% end %>
    <%= yield %>
  </body>


6 . Create The Home Page

i) Generate the controller and view

$ rails g controller home index


ii) Open the home page in app/views/home/index.html.erb and add this code

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

<div class="container mt-3">
  <h3>See if bootstrap is working</h3>
  
  <button type="button" class="btn btn-primary" data-bs-toggle="tooltip" title="Yay! Its' working.">
    Hover over me!
  </button>  
</div>

<div class="container mt-3">
  <h3>See if jquery is working</h3>
  
  <button type="button" class="btn btn-primary" id="jq-test">
    Click me!
  </button>
</div>
   


ii) Create home.js file in app/javascript/src and add this jquery code.

 
// javascript/src/home.js

$("#jq-test").click(function(){
  alert("Jquery is working!")
});
 


iii) Import home.js in app/javascript/application.js

 
// app/javascript/src/application.js
// ...

import "./src/home"
 


iv) Set home page as the default route in config/routes.rb

# config/routes.rb
 
  root "home#index"


Testing the app

To run the app, cd into the root of the project and issue this command:

$ bin/dev

Now navigate to localhost:3000. The two buttons should be working if you’ve made the configurations described here. If you wish to change the default port, open the Procfile.dev file located in the root of the project and change the port number.

// /Procfile.dev
// ...

web: bin/rails server -p 3000
js: yarn build --watch
css: yarn build:css --watch


Something to remember

If you are going to use inline or embedded javascript in your app pages, jquery will not work.

For jquery to work, in app/views/layouts/application.html.erb, set defer: false in the javascript_include_tag. If the option is set to true, the browser will throw this error Uncaught ReferenceError: $ is not defined.

NB: Defer loads javascript last to prevent it from blocking app content from loading. Therefore, defer: false can prevent the app from loading smoothly i.e makes the page appear to freeze halfway through the rendering. You’re better off using external scripts.


We have covered the necessary configurations for the project. If you run the app, you should now be able to use jquery and bootstrap to build the project.

Thanks for reading, see you in the next one!