CRUD in Rails 7
Tags: rails, ruby, beginners, database
Published: 2023-02-12 18:34:13


## 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) )](https://cdn-images-1.medium.com/max/2560/1*a-5ye9201mCJkrw_lljXyA.png)

We are going to use **Rails 7.0.4.2** and **Ruby 3.1.0** for this project.
&nbsp;

## **Points To be Discussed**

* What is CRUD?

* Create a new rails application

* Create Model

* Create Controller

* Create CRUD

* Screenshots

* References

&nbsp;
## 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

&nbsp;
## Create a new rails application

to create a new rails application type,

    rails new Employee_CRUD

&nbsp;
## 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](https://cdn-images-1.medium.com/max/2000/1*blLN-joDN9XbL2x1_9RIrA.png)

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.

&nbsp;
## 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](https://cdn-images-1.medium.com/max/2000/1*F2--WW1ilJETJDTGRkd8LA.png)

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/](http://localhost:3000/employees/index) in your browser. it will look like,

![rails 7 homepage after starting the server](https://cdn-images-1.medium.com/max/3840/1*-c36aGbmBJNU4bHNKX1B1w.png)

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

![the index page of our application](https://cdn-images-1.medium.com/max/2620/1*rrxepSY0Th93-6RhVU5ouQ.png)

&nbsp;
## 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

&nbsp;
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

&nbsp;
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>

&nbsp;
**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._**

&nbsp;
**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>

&nbsp;
**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>

&nbsp;
**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.***

&nbsp;
**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>

&nbsp;
That’s it. Our CRUD has been done. 🎉 🎉

Now just go to [http://localhost:3000/](http://localhost:3000/). and enjoy your CRUD application.

&nbsp;
## **Screenshots:**

**Index Page**

![[http://localhost:3000/employees](http://localhost:3000/employees) OR [http://localhost:3000/](http://localhost:3000/)](https://cdn-images-1.medium.com/max/2144/1*HUXzI7zSYweJ6eOpeuMh9g.png)

&nbsp;
**New Page**

![[http://localhost:3000/employees/new](http://localhost:3000/employees/new)](https://cdn-images-1.medium.com/max/2160/1*HjTQaGT37TwWNbMbuXuDwg.png)

&nbsp;
**Show Page**

![[http://localhost:3000/employees/1](http://localhost:3000/employees/1)](https://cdn-images-1.medium.com/max/2092/1*5PvjhSCNGRonCkFG-GQJYA.png)

&nbsp;
**Edit Page**

![[http://localhost:3000/employees/1/edit](http://localhost:3000/employees/1/edit)](https://cdn-images-1.medium.com/max/2000/1*SYYd_4g9cwQrV5s52g3-KQ.png)

&nbsp;
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.

&nbsp;
**custom.css**

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

&nbsp;
## References :

GitHub Repository : [https://github.com/rutikkpatel/Employee-CRUD-Rails-7](https://github.com/rutikkpatel/Employee-CRUD-Rails-7)