CRUD in Rails 7

Rutik Patel
7 min readFeb 12, 2023

--

In this article, we are going to create a CRUD application in rails 7.

CRUD in rails 7 Cover Image created by Rutik Patel
Created By Author ( Rutik Patel )

We are going to use Rails 7.0.4.2 and Ruby 3.1.0 for this project.

Points To be Discussed

  • What is CRUD?
  • Create a new rails application
  • Create Model
  • Create Controller
  • Create CRUD
  • Screenshots
  • References

What is CRUD?

The CRUD operation is a fundamental and extremely basic operation for any programming language. It stands for Create, Read, Update, and Delete. Most often, it is used to create the data, alter the data, and delete the data from the database.

Rails by default use SQLite database

Create a new rails application

to create a new rails application type,

rails new Employee_CRUD

Create Model

rails g model Employee employee_name gender hobbies

it will create and invoke these kinds of files

create and invoke files after generating the model

We are using the rails generator to generate the model and passing employee_name, gender, and hobbies as database fields. Moreover, It will create a migration file in db/migrate folder and it looks like

class CreateEmployees < ActiveRecord::Migration[7.0]
def change
create_table :employees do |t|
t.string :employee_name
t.string :gender
t.string :hobbies

t.timestamps
end
end
end

Run rails db:migrate . it will run the above migration file.

Create Controller

Now, run

rails g controller employees index new create show edit update destroy

It will generate a controller, namely, employees_controller.rb.

Apart from this controller, this command also generates view files inside the views folder and defines some routes in the routes.rb file.

create and invoke files after generating the controller

It will create 7 views of the file as we type index, new, create, show, edit, update, and destroy in the command.

→ index.html.erb

→ new.html.erb

→ create.html.erb

→ show.html.erb

→ edit.html.erb

→ update.html.erb

→ destroy.html.erb

And in config/routes.rb it looks like

Rails.application.routes.draw do
get 'employees/index'
get 'employees/new'
get 'employees/create'
get 'employees/show'
get 'employees/edit'
get 'employees/update'
get 'employees/destroy'
end

Start the rails server by rails s and goes to http://localhost:3000/ in your browser. it will look like,

rails 7 homepage after starting the server

type http://localhost:3000/employees/index in your URL bar to visit the index page. it will look like

the index page of our application

CREATE CRUD

So now that our model, view, and controller have been generated, we can write the code for CRUD inside these files.

Before writing controller actions, we need to modify routes first, hence change the individual get routes into one single resource and add index page as a root page.

config/routes.rb

Rails.application.routes.draw do
resources :employees
root "employees#index"
end

Let us now move to the controller and write the following code:

employees_controller.rb

class EmployeesController < ApplicationController
before_action :set_employee_params, only: %i[show edit update destroy]

def index
@employees = Employee.all
end

def new
@employee = Employee.new
end

def create
@employee = Employee.create(employee_params)
if @employee.valid?
flash[:errors] = 'Employee Created Successfully'
redirect_to employees_path
else
flash[:errors] = @employee.errors.full_messages
render :new
end
end

def show; end

def edit; end

def update
if @employee.update(employee_params)
flash[:errors] = 'Employee Updated Successfully'
redirect_to employee_path(@employee)
else
flash[:errors] = @employee.errors.full_messages
redirect_to edit_employee_path
end
end

def destroy
if @employee.delete
flash[:errors] = 'Employee Deleted Successfully'
redirect_to root_path(@employee)
else
flash[:errors] = @employee.errors.full_messages
redirect_to destroy_employee_path
end
end

private

def set_employee_params
@employee = Employee.find(params[:id])
end

def employee_params
params.require(:employee).permit(:employee_name, :gender, { hobbies: [] })
end
end

Now let’s modify the view files.

I am going to create a CRUD with some styling, and I will be using Bootstrap for that.

Add Bootstrap 5’s following CDN to application.html.erb

<!--Bootstrap CDN  -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

application.html.erb

<!DOCTYPE html>
<html>
<head>
<title>EmployeeCrud</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>

<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
</head>
<!--Bootstrap CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

<body>
<%= yield %>
</body>
</html>

NOTE: We do not need the create, update, or destroy erb files. Because create is as same as new, an update is as same as edit, and destroy is directly run with the method defined in the controller. So, you can delete it.

index.html.erb

<div class="flex-column" style = "height: auto;">
<h1> Employees </h1>
<!--Error Message-->
<% if flash[:errors] %>
<% flash.each do |name,message| %>
<p class="text-danger"><%= message%></p>
<% end %>
<% end %>
<!-- Employee Table -->
<div>
<table class="table table-info table-striped">
<ol class="fs-2">
<thead class="table-secondary">
<td class="text-center"> Id </td>
<td class="text-center"> Name </td>
<td class="text-center"> Hobbies </td>
<td colspan=3 class="text-center"> Action </td>
</thead>
<% @employees.each do |e| %>
<tr>
<td class="text-center"> <%= e.id %> </td>
<td class="text-center"> <%= link_to e.employee_name, employee_path(e) %> </td>
<td class="text-center"> <%= e.hobbies %> </td>
<td class="text-center"><%= button_to "Show",employee_path(e),method: :get, class:"btn-success border-0 rounded-pill shadow px-3 py-2" %></td>
<td class="text-center"><%= button_to "Edit",edit_employee_path(e),method: :get, class:"btn-primary border-0 rounded-pill shadow px-3 py-2" %></td>
<td class="text-center"><%= button_to "Delete",employee_path(e),method: :delete, class:"btn-danger border-0 rounded-pill shadow px-3 py-2" %></td>
</tr>
<% end %>
</ol>
</table>
</div>
<div class="d-flex">
<%= button_to "Add New Employee", new_employee_path, method: :get ,class:"btn-warning border-0 rounded-pill shadow p-3 m-3" %>
</div>
</div>

new.html.erb

<div class="flex-column">
<div class="card shadow" style="width: 36rem;">
<div class="card-header">
<h2 class="text-center">Employee Form</h2>
</div>
<div class="card-body">
<!--Error Message-->
<% if flash[:errors] %>
<% flash[:errors].each do |error| %>
<p class="text-danger"><%= error %></p>
<% end %>
<% end %>
<!-- Form Started Here -->
<%= form_with model: @employee do |f| %>
<%= f.label :employee_name, "Employee Name :", class:"mt-3" %>
<%= f.text_field :employee_name ,placeholder: "Enter Employee's Name",class:"mb-2 form-control" %>
<br>
<!-- Radio Button For Gender -->
<div class="form-group">
<%= f.label "Gender :" %>
<%= f.radio_button :gender, "male" %>
<%= f.label :gender, "Male" %>
<%= f.radio_button :gender, "female" %>
<%= f.label :gender, "Female" %>
</div>
<br>
<!-- Checkbox For Hobbies -->
<div class="form-group">
<%= f.label "Hobbies :" %>
<%= f.check_box :hobbies, { multiple: true },"Reading", false %>
<%= f.label :hobbies, "Reading" %>
<%= f.check_box :hobbies, { multiple: true },"Photography", false %>
<%= f.label :hobbies, "Photography" %>
<%= f.check_box :hobbies, { multiple: true },"Travelling", false %>
<%= f.label :hobbies, "Travelling" %>
</div>
<br>
<%= f.submit "Save Employee", class:"btn-primary border-0 rounded-pill shadow p-3" %>
<% end %>
</div>
</div>
</div>

edit.html.erb

<div class="flex-column">
<div class="card shadow" style="width: 36rem;">
<div class="card-header">
<h2 class="text-center">Employee Form</h2>
</div>
<div class="card-body">
<!--Error Message-->
<% if flash[:errors] %>
<% flash[:errors].each do |error| %>
<p class="text-danger"><%= error %></p>
<% end %>
<% end %>
<!-- Form Started Here -->
<%= form_with model: @employee do |f| %>
<%= f.label :employee_name, "Employee Name :", class:"mt-3" %>
<%= f.text_field :employee_name ,placeholder: "Enter Employee's Name",class:"mb-2 form-control" %>
<br>
<!-- Radio Button For Gender -->
<div class="form-group">
<%= f.label "Gender :" %>
<%= f.radio_button :gender, "male" %>
<%= f.label :gender, "Male" %>
<%= f.radio_button :gender, "female" %>
<%= f.label :gender, "Female" %>
</div>
<br>
<!-- Checkbox For Hobbies -->
<div class="form-group">
<%= f.label "Hobbies :" %>
<%= f.check_box :hobbies, { multiple: true },"Reading", false %>
<%= f.label :hobbies, "Reading" %>
<%= f.check_box :hobbies, { multiple: true },"Photography", false %>
<%= f.label :hobbies, "Photography" %>
<%= f.check_box :hobbies, { multiple: true },"Travelling", false %>
<%= f.label :hobbies, "Travelling" %>
</div>
<br>
<%= f.submit "Save Employee", class:"btn-primary border-0 rounded-pill shadow p-3" %>
<% end %>
</div>
</div>
</div>

Note : We have the same code in new.html.erb and edit.html.erb, so we will use the _form.html.erb partial for that and just render that partial in our files. We will do this after learning about “Rails Partials” in our upcoming articles.

show.html.erb

<!-- Employee Details Showing -->
<div class="flex-column" style="height:100vh;">
<!--Error Message-->
<% if flash[:errors] %>
<% flash.each do |name,message| %>
<p class="text-danger"><%= message%></p>
<% end %>
<% end %>
<div class="d-flex">
<div class="m-5" >
<div class="card bg-light border-warning shadow">
<div class="card-body">
<div class="card-header">
<h2 class="text-center">Employee's Details</h2>
</div>
<div>
<h2> &#10145; ID: <%= @employee.id %> </h2>
<h2> &#10145; Name: <%= @employee.employee_name %> </h2>
<h2> &#10145; Gender: <%= @employee.gender %> </h2>
<h2> &#10145; Hobbies: <%= @employee.hobbies %> </h2>
</div>
<div class="d-flex">
<%= button_to "Edit Employee" , edit_employee_path, method: :get ,class:"btn-success border-0 rounded-pill shadow p-2 m-2" %>
<%= button_to "Delete Employee", employee_path, method: :delete ,class:"btn-danger border-0 rounded-pill shadow p-2 m-2" %>
<%= button_to "View all Employee", employees_path,method: :get ,class:"btn-primary border-0 rounded-pill shadow p-2 m-2" %>
</div>
</div>
</div>
</div>
</div>
</div>

That’s it. Our CRUD has been done. 🎉 🎉

Now just go to http://localhost:3000/. and enjoy your CRUD application.

Screenshots:

Index Page

This image depicts the index page of our Employee CRUD application.
http://localhost:3000/employees OR http://localhost:3000/

New Page

This image depicts the new page of our Employee CRUD application.
http://localhost:3000/employees/new

Show Page

This image depicts the show page of our Employee CRUD application.
http://localhost:3000/employees/1

Edit Page

This image depicts the edit page of our Employee CRUD application.
http://localhost:3000/employees/1/edit

In addition, if you want to change some styling in your application, you can do it.

You just need to create a custom.css file under the app/assets/stylesheets folder and write your own style. I create the same and add styling for centering a div.

custom.css

.set-center {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}

References :

GitHub Repository : https://github.com/rutikkpatel/Employee-CRUD-Rails-7

--

--