Ruby on Rails Integration

How to use Bootstrap 5 with Ruby on Rails - free starter

This guide will provide you with a free template for a Ruby on Rails application, with MySQL database and Bootstrap 5 front-end.


Prerequisites

Before starting the project make sure to install the following utilities:

  • Node LTS (14.x.x or higher recommended)
  • Ruby version 2.7.0 or later
  • MySQL (8.x.x or higher recommended)
  • Yarn (1.22.19 or higher recommended)
  • MDB GO
  • Code editor. We recommend VSCode

Creating a new Ruby on Rails application

Let's create a fresh Ruby on Rails application so that we can go through all the steps together. For this tutorial we'll be using MySQL database.

Step 1

Install Ruby on Rails on your computer.

        
            
        gem install rails
      
        
    

Step 2

Navigate within the terminal to the directory where you want to create your application then run the code from the snippet below to create your app and change the directory.

        
            
      rails new toDoApp -j esbuild -d mysql
      cd toDoApp
      
        
    

Note: In case of an error bound to the installation of the mysql2 gem, check the solution from this Github thread.

Step 3

Create a controller, model, and database for handling endpoints. Task is the name of your file - you can change whatever you like. After that you should have new files in app/controllers, app/models and db/migrate directory - in this particular case all of them will have the name Tasks (framework creates the plural on its own).

        
            
        bin/rails generate scaffold task name:text description:text
      
        
    
        
            
        ruby bin\rails generate scaffold task name:text description:text
      
        
    

Step 3

Creating a MySQL database.

In order to create a new database you need to run the following command.

Note: If you don't have MDB CLI installed yet, you can do it with NPM: npm install -g mdb-cli. Now log in with your MDB account, type: mdb login. If you don't have account yet you can create one using mdb register command.

        
            
          mdb database init -db mysql8
        
        
    
  • Create a new user
  • Provide username, password, database name and description.

CLI will display your username, password, database name and connections string. You will need this data in the next step. Now you can go to phpMyAdmin where you will be able to handle the administration of the MySQL database.

Note: the password must contain at least one uppercase letter, one lowercase letter, one number, one special symbol and have minimum length of 8.

Step 4

In the database.yml file go to the development section and add the database connection details. Change the values between brackets for the ones you got after creating a new MySQL Database from our starter.

        
            
      development:
        adapter: mysql2
        host: mysql.db.mdbgo.com
        database: [Database Name]
        username: [Username]
        password: [Password]
      
        
    

Step 6

Migrate a database.

        
            
        bin/rails db:migrate
      
        
    
        
            
        ruby bin\rails db:migrate
      
        
    

Step 7

Run your server with a command from the snippet below.

        
            
        bin/dev
      
        
    
        
            
        rails s
      
        
    

This will boot Puma which is the default Ruby web server. To access your application via any browser visit http://localhost:3000/. There you should see the Rails default information page. When you want to stop the web server, press Ctrl+C in the terminal window where it's running.


Install MDB

In this section, we will add MDB styles and JavaScript files to the Ruby on Rails app.

Step 1

From the base project directory type the following command in the terminal. It will change the directory to vendor and initialize MDB CLI. From the list of starters select Standard.

Note: If you don't have MDB CLI installed yet, you can do it with NPM: npm install -g mdb-cli. Now log in with your MDB account, type: mdb login. If you don't have account yet you can create one using mdb register command.

        
            
        cd vendor
        mdb frontend init mdb5-free-standard
      
        
    

Step 2

Add vendor to assets path in config/initializers/assets.rb file.

        
            
        Rails.application.config.assets.paths << Rails.root.join('vendor')
      
        
    

Step 3

In the application.css file import CSS files.

        
            
        @import "mdb5-free-standard/css/mdb.min.css"
      
        
    

Step 4

In the application.js add those lines to import JS files.

        
            
        import * as mdb from "../../vendor/mdb5-free-standard/js/mdb.umd.min.js"
        window.mdb = mdb;
      
        
    

To Do App with MDB

In this section, we will present the capabilities of Ruby on Rails used with the MDB package by creating an example To Do App.

Step 1

From ./app/views/tasks remove unnecessary files leaving _form.html.erb, _task.html.erb and index.html.erb.

Step 2

We are going to modify default GET, POST, PUT/PATCH and DELETE endpoints that support the functionality of the front-end app. To do that go to tasks_controller.rb and replace its content with code from the snippet below.

        
            
          class TasksController < ApplicationController
            before_action :set_task, only: %i[ show edit update destroy ]
          
            # GET /tasks or /tasks.json
            def index
              @tasks = Task.all
            end
          
            # POST /tasks or /tasks.json
            def create
              @task = Task.new(name: params[:name], description: params[:description])
          
              respond_to do |format|
                if @task.save
                  format.html { redirect_to tasks_url, notice: "Task was successfully created." }
                else
                  format.html { redirect_to tasks_url, status: :unprocessable_entity }
                end
              end
            end
          
            # PATCH/PUT /tasks/1 or /tasks/1.json
            def update
              respond_to do |format|
                if @task.update(name: params[:name], description: params[:description])
                  format.html { redirect_to tasks_url, notice: "Task was successfully updated." }
                else
                  format.html { redirect_to tasks_url, status: :unprocessable_entity }
                end
              end
            end
          
            # DELETE /tasks/1 or /tasks/1.json
            def destroy
              @task.destroy
          
              respond_to do |format|
                format.html { redirect_to tasks_url, notice: "Task was successfully destroyed." }
              end
            end
          
            private
              # Use callbacks to share common setup or constraints between actions.
              def set_task
                @task = Task.find(params[:id])
              end
          
              # Only allow a list of trusted parameters through.
              def task_params
                params.require(:task).permit(:name, :description)
              end
          end
        
        
    

Step 3

At the end of the head tag in the application.html.erb file add the content of the snippet below.

        
            
          <!-- Font Awesome -->
          <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"/>
          <!-- Google Fonts -->
          <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet"/>
        
        
    

Step 4

At the end of the body tag in the application.html.erb file add the content of the snippet below.

        
            
          <script type="module">
            document.querySelectorAll('.form-outline').forEach((formOutline) => {
              new mdb.Input(formOutline).update();
            });
            let taskForm, taskModalLabel, editNameInput, editDescInput, addTaskButton;
          </script>
        
        
    

Step 5

In ./app/views/tasks prepare partials _form.html.erb and _task.html.erb by replacing its current content with the content of the snippets below.

        
            
          <%= form_with(model: task) do |form|  %>
            <div class="modal-body">
                <div class="form-outline mb-4" data-mdb-input-init>
                    <%= form.text_field :name, class: "form-control", id: "editNameInput" %>
                    <%= form.label :name, class: "form-label", for: "editNameInput" %>
                </div>

                <div class="form-outline mb-4" data-mdb-input-init>
                    <%= form.text_field :description, class: "form-control", id: "editDescInput"%>
                    <%= form.label :description, class: "form-label", for: "editDescInput" %>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-mdb-dismiss="modal" data-mdb-ripple-init>Close</button>
                <%= form.button "Save", type: "submit", class: "btn btn-primary", id: "confirmButton", "data-mdb-ripple-init" => true %>
            </div>
          <% end %>
        
        
    
        
            
          <div id="<%= dom_id task %>">
            <div class="fw-bold name"><%= task.name %></div>
            <div class="fw-bold desc"><%= task.description %></div>
          </div>
        
        
    

Step 6

In ./app/views/tasks/index.html.erb paste the content of the snippet below.

        
            
        <div class="row pt-5">
          <div class="col text-center">
              <button class="btn btn-primary" data-mdb-modal-init data-mdb-ripple-init  data-mdb-target="#TaskModal" id="addTaskButton">Add
                  task</button>
          </div>
        </div>
      
        <div id="tasks">
            <!-- List of tasks -->
            <div class="row mt-3 p-5">
                <div class="col d-flex justify-content-center align-items-center">
                    <ul class="list-group list-group-light" style="min-width: 22rem;">
                        <% @tasks.each do |task| %>
                        <li class="list-group-item d-flex justify-content-between align-items-center gap-5" id="<%= task.id %>">
                            <%= render task %>
                            <div class="d-flex align-items-center">
                                <button class="btn btn-primary btn-floating me-2" data-mdb-modal-init data-mdb-ripple-init
                                    data-mdb-target="#TaskModal" id="addTaskButton"
                                    onclick="setModalValues(<%= task.id %>)"><span class="fas fa-pen text-white"
                                        title="edit"></span></button>
                                <%= button_to task, method: :delete, class:"btn btn-danger btn-floating", "data-mdb-ripple-init" => true do%>
                                <span class="fas fa-trash text-white" title="delete"></span>
                            <% end %>
                            </div>
                        </li>
                        <% end %>
                </div>
            </div>
        </div>
        
      
        <!-- Modal Add -->
        <div class="modal fade" id="TaskModal" tabindex="-1" aria-labelledby="TaskModalLabel" aria-hidden="true"
            data-mdb-backdrop="false">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="taskModalLabel">Add task</h5>
                        <button type="button" class="btn-close" data-mdb-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <%= render "form", task: @task, method: :post %>
                </div>
            </div>
        </div>
      
      <script>
          taskForm = document.querySelector("#TaskModal form");
          taskModalLabel = document.getElementById('taskModalLabel');
          editNameInput = document.getElementById('editNameInput');
          editDescInput = document.getElementById('editDescInput');
      
      
          function setModalValues(id) {
              taskModalLabel.innerText = 'Edit task';
              const task = document.getElementById(id)
              editNameInput.value = task.querySelector('.name').innerText;
              editDescInput.value = task.querySelector('.desc').innerText;
              taskForm.action = `/tasks/${id}`;
              taskForm.method = 'put';
          }
      
          addTaskButton = document.querySelector('#addTaskButton');
          addTaskButton.addEventListener('click', () => {
              taskModalLabel.innerText = 'Add task';
              taskForm.reset();
              taskForm.action = `/tasks`;
              taskForm.method = 'post';
          })
      </script>
        
        
    

To access your application visit http://localhost:3000/tasks. There you should see a simple To Do app connected to MySQL database.

Important: For Windows users, some more steps need to be taken. Please follow the steps below.

Additional step 1

In the package.json change scripts to match the content of the snippet below.

        
            
            "scripts": {
              "build": "esbuild app/javascript/application.js --bundle --sourcemap --outdir=app/assets/builds --public-path=assets",
              "watch": "esbuild app/javascript/application.js --bundle --sourcemap --outdir=app/assets/builds --public-path=assets --watch"
            }
          
        
    

Additional step 2

From toDoApp directory run the watch script to watch changes in your JavaScript and CSS files.

        
            
          npm run watch
        
        
    

Additional step 3

Restart your server to see changes.


Optimization

If you want to further optimize your application please visit:


Backend features

Ruby on Rails:

This example was created with the use of Ruby on Rails. Our app is connected to MySQL database and is ready to receive get, post, put and delete requests.

MDB CLI:

The database in this example was created using MDB CLI with Graphical User Interface available under phpmyadmin.mdbgo.com


Frontend features

MDB UI KIT:

We have successfully added MDB UI Kit to the created app, with which we can build basic views very quickly.

Views and Layouts:

We have successfully integrated the backend with the MDB package and can send basic requests to backend Ruby on Rails application.