DEV Community

Rutvik Patel
Rutvik Patel

Posted on • Originally published at Medium

CRUD in Rails 7

CRUD in Rails 7

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

Created By [Author](https://medium.com/@rutikkpatel) ( [Rutik Patel](https://medium.com/@rutikkpatel) )

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
Enter fullscreen mode Exit fullscreen mode

 

Create Model

rails g model Employee employee_name gender hobbies
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

 
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
Enter fullscreen mode Exit fullscreen mode

 
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>
Enter fullscreen mode Exit fullscreen mode

 
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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

 
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>
Enter fullscreen mode Exit fullscreen mode

 
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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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

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

 

Screenshots:

Index Page

[http://localhost:3000/employees](http://localhost:3000/employees) OR [http://localhost:3000/](http://localhost:3000/)

 
New Page

[http://localhost:3000/employees/new](http://localhost:3000/employees/new)

 
Show Page

[http://localhost:3000/employees/1](http://localhost:3000/employees/1)

 
Edit Page

[http://localhost:3000/employees/1/edit](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;
}
Enter fullscreen mode Exit fullscreen mode

 

References :

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

Top comments (2)

Collapse
 
superails profile image
Yaroslav Shmarov

small remark: create, update, delete are not get requests

Collapse
 
rutikkpatel profile image
Rutvik Patel • Edited

First and foremost, thank you so much @superails for taking the time to read my article. Your youtube tutorials are extremely beneficial to my learning. 

And, yes, you are correct. create , update , delete are not get requests.

A POST request is to "create."

The PATCH request is "update".

A DESTROY or DELETE request is to "delete".

But when we generate the controller with rails g controller employees index new create show edit update destroy . The routes will be automatically added as

get 'employees/create'
get 'employees/update'
get 'employees/destroy'

Image description