[RUBY] Create an EC site with Rails5 ⑤ ~ Customer model ~

Introduction

This is a continuation of the series that creates an EC site where you can shop at a fictitious bakery, Create an EC site with Rails 5 ④. Finally, we will start implementing the function. First of all, in order from the parent model peripheral functions of the customer site ... So, this time we will focus on the CRUD of the Customer model.

Source code

https://github.com/Sn16799/bakeryFUMIZUKI

devise controller

I couldn't register new with devise, and when I wondered why, it turned out that I didn't give the parameter permission to the controller side.

app/controllers/customers/registrations_controller.rb


class Customers::RegistrationsController < Devise::RegistrationsController

  before_action :authenticate_customer!
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def after_sign_up_path_for(resource)
    customer_top_path
  end

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:is_active, :first_name, :first_name_kana, :family_name, :family_name_kana, :post_code, :address, :tel])
  end

  protected
  def update_resouce(resource, parans)
    resource.update_without_password(params)
  end

end

By the way, sessions_controller also specified the transition destination after login and logout.

app/controllers/customers/sessions_controller.rb


class Customers::SessionsController < Devise::SessionsController

  protected

  def after_sign_in_path_for(resource)
    customer_top_path
  end

  def after_sign_out_path_for(resource)
    customer_top_path
  end

end

Enable Bootstrap flash

With Bootstrap, you can use neatly organized flash messages just by specifying the class. It is convenient to create a partial template so that you can call it with render.

app/controllers/application_controller.rb


add_flash_types :success, :danger, :info

app/helpers/application_helper.rb


def flash_class_for flash_type
  case flash_type
    when 'success' then 'alert-success'
    when 'danger' then 'alert-danger'
    when 'info' then 'alert-info'
  end
end

html:app/views/layouts/_flash.html.erb


<% flash.each do |type, msg| %>
  <div class="alert <%= flash_class_for(type) %> row" role="alert">
    <a class="close" data-dismiss="alert">×</a>
    <%= msg %>
  </div>
<% end %>

html:app/views/layouts/application.html.erb


<body>
  <%= render 'layouts/header' %>
  <div class="container-fluid">
    <%= render 'layouts/flash', flash: flash %>
    <div class="row">
      <%= yield %>
    </div>
  </div>
  <%= render 'layouts/footer' %>
</body>

Controller Many features are basic CRUD, but only the unsubscription process is different.

Press the "Unsubscribe" button on the edit screen (call withdraw action)
↓
Transition to the withdrawal confirmation screen
↓
Press the "Unsubscribe" button (alert appears)
↓
If you press "Yes", the withdrawal process will be performed (withdraw)_done action call)

The flow is as above. In addition, the withdrawal process is not the process of deleting Customer data, but the process of changing the is_active column from true to false.

app/controllers/customers_controller.rb


class CustomersController < ApplicationController

  before_action :authenticate_customer!
  before_action :set_customer
  before_action :baria_customer

  def edit
  end

  def show
  end

  def update
    @customer = current_customer
    if @customer.update(customer_params)
      redirect_to customer_path(@customer), success: 'Customer information has been updated!'
    else
      flash[:danger] = 'The customer information could not be updated. Are there any blanks?'
      render :edit
    end
  end

  def withdraw
  end

  def withdraw_done
    @customer = current_customer
    @customer.update(is_active: false)
    reset_session
    redirect_to customer_top_path, info: 'Thank you very much. We look forward to seeing you again.'
  end

  private

  def customer_params
    params.require(:customer).permit(:is_active, :first_name, :first_name_kana, :family_name, :family_name_kana, :post_code, :address, :email, :tel, cart_items_attributes: [:_destroy])
  end

  def set_customer
    @customer = current_customer
  end

  #When you try to access someone else's page, you return to the previous page
  def baria_customer
    if params[:id].to_i != current_customer.id
      redirect_back(fallback_location: root_path)
    end
  end
end

View Sign_up

html:app/views/customers/registrations/new.html.erb


<div class='col-lg-6 offset-lg-3 offset-2 space'>
  <div class='row'>
    <h2>New member registration</h2>
  </div>

  <div class='row'>
    <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
    <%= render 'devise/shared/error_messages', resource: resource %>


    <div class='form-group row space'>
      <div class='col-lg-4'>
        <h5><%= f.label :name%></h5>
      </div>
      <div class='col-lg-8'>
        <div class="row">
          <div class="col-lg-6">
            (Surname)<%= f.text_field :family_name, autofocus: true, autocomplete: 'family_name', class: 'form-control' %>
          </div>
          <div class="col-lg-6">
            (Name)<%= f.text_field :first_name, autofocus: true, autocomplete: 'first_name', class: 'form-control' %>
          </div>
        </div>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :Frigana%></h5>
      </div>
      <div class='col-lg-8'>
        <div class="row">
          <div class="col-lg-6">
            (Surname)<%= f.text_field :family_name_kana, autofocus: true, autocomplete: 'family_name_kana', class: 'form-control' %>
          </div>
          <div class="col-lg-6">
            (Mei)<%= f.text_field :first_name_kana, autofocus: true, autocomplete: 'first_name_kana', class: 'form-control' %>
          </div>
        </div>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :Email%></h5>
      </div>
      <div class='col-lg-8'>
        <%= f.text_field :email, autofocus: true, autocomplete: 'email', class: 'form-control' %>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :Zip code (without hyphens)%></h5>
      </div>
      <div class='col-lg-8'>
        <%= f.text_field :post_code, autofocus: true, autocomplete: 'post_code', class: 'form-control' %>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :Street address%></h5>
      </div>
      <div class='col-lg-8'>
        <%= f.text_field :address, autofocus: true, autocomplete: 'address', class: 'form-control' %>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :Phone number (no hyphen)%></h5>
      </div>
      <div class='col-lg-8'>
        <%= f.text_field :tel, autofocus: true, autocomplete: 'tel', class: 'form-control' %>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :Password (6 characters or more)%></h5>
      </div>
      <div class='col-lg-8'>
        <%= f.password_field :password, autocomplete: 'new-password', class: 'form-control' %>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :For password confirmation%></h5>
      </div>
      <div class='col-lg-8'>
        <%= f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control' %>
      </div>
    </div>

    <div class='row'>
      <div class='col-lg-2 offset-lg-5 actions'>
        <%= f.submit 'sign up', class:'btn btn-danger' %>
      </div>
    </div>

    <% end %>
  </div>

  <div class="space">
    <h4>Those who have already registered</h4>
    <h5><%= link_to 'Here', new_customer_session_path  %>Please log in from</h5>
  </div>
</div>

Sign_in

html/app/views/customers/sessions/new.html.erb


<div class='col-lg-6 offset-lg-4 offset-1 space'>
  <div class="row">
    <h3>
      <span style="display: inline-block;">For members</span>
      <span style="display: inline-block;">Login from here</span>
    </h3>
  </div>

  <div class="row">
    <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
    <%= render 'devise/shared/error_messages', resource: resource %>

    <div class="form-group row space">
      <div class="col-lg-4">
        <h5><%= f.label :Email%></h5>
      </div>
      <div class="col-lg-8">
        <%= f.text_field :email, autofocus: true, autocomplete: "email", class: 'form-control' %>
      </div>
    </div>

    <div class="form-group row">
      <div class="col-lg-4">
        <h5><%= f.label :password%></h5>
      </div>
      <div class="col-lg-8">
        <%= f.password_field :password, autocomplete: "current-password", class: 'form-control' %>
      </div>
    </div>

    <div>
      <%= link_to "=>If you forgot your password, click here", new_password_path(resource_name) %>
    </div>

    <div class="form-group row space">
      <div class="col-lg-2 offset-lg-5">
        <%= f.submit "Login", class:"btn btn-danger" %>
      </div>
    </div>

    <% end %>
  </div>

  <div class="space">
    <h4>Those who have not registered</h4>
    <h5><%= link_to "Here", new_customer_registration_path  %>Please register from.</h5>
  </div>

</div>

Edit

html:app/views/customers/edit.html.erb


<div class='col-lg-10 offset-lg-1 space'>
  <div class='row'>
    <h2>Edit registration information</h2>
  </div>

  <div class='row'>
    <%= form_with(model: @customer, local: true, class: 'container') do |f| %>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :name%></h5>
      </div>
      <div class='col-lg-8'>
        <span style='display: inline-block;'>
          (Surname)<%= f.text_field :family_name, autofocus: true, autocomplete: 'family_name', class: 'form-control' %>
        </span>
        <span style='display: inline-block;'>
          (Name)<%= f.text_field :first_name, autofocus: true, autocomplete: 'first_name', class: 'form-control' %>
        </span>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :Frigana%></h5>
      </div>
      <div class='col-lg-8'>
        <span style='display: inline-block;'>
          (Surname)<%= f.text_field :family_name_kana, autofocus: true, autocomplete: 'family_name_kana', class: 'form-control' %>
        </span>
        <span style='display: inline-block;'>
          (Mei)<%= f.text_field :first_name_kana, autofocus: true, autocomplete: 'first_name_kana', class: 'form-control' %>
        </span>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :Email%></h5>
      </div>
      <div class='col-lg-8'>
        <%= f.text_field :email, autofocus: true, autocomplete: 'email', class: 'form-control' %>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :Zip code (without hyphens)%></h5>
      </div>
      <div class='col-lg-8'>
        <%= f.text_field :post_code, autofocus: true, autocomplete: 'post_code', class: 'form-control' %>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :Street address%></h5>
      </div>
      <div class='col-lg-8'>
        <%= f.text_field :address, autofocus: true, autocomplete: 'address', class: 'form-control' %>
      </div>
    </div>

    <div class='form-group row'>
      <div class='col-lg-4'>
        <h5><%= f.label :Phone number (no hyphen)%></h5>
      </div>
      <div class='col-lg-8'>
        <%= f.text_field :tel, autofocus: true, autocomplete: 'tel', class: 'form-control' %>
      </div>
    </div>

    <div class="form-group row">
      <div class="col-lg-4 offset-lg-8">
        <%= f.submit 'Save your edits', class:'btn btn-danger' %>
        <%= link_to 'Withdraw', customer_withdraw_path(@customer), class:'btn btn-danger'  %>
      </div>
    </div>
    <% end %>
  </div>
</div>

Details

html:app/views/customers/show.html.erb


<div class="col-lg-6 offset-lg-3 space">
  <div class="container">
    <h2>My page</h2>
  </div>
  <!--Customer Information-->
  <div class="container space">
    <div class="row">
      <div class="col-lg-5"><h3>Customer Information</h3></div>
      <div class="col-lg-2">
        <%= link_to 'Edit', edit_customer_path, class: 'btn-sm btn-danger' %>
      </div>
      <div class="col-lg-4">
        <%= link_to 'Change Password', new_customer_password_path, class: 'btn-sm btn-danger' %>
      </div>
    </div>

    <div class="row">
      <div class="col-lg-3">
        <h4>Full name</h4>
      </div>
      <div class="col-lg-9">
        <%= @customer.full_name %>
      </div>
    </div>

    <div class="row">
      <div class="col-lg-3">
        <h4>Kana</h4>
      </div>
      <div class="col-lg-9">
        <%= @customer.family_name_kana %> <%= @customer.first_name_kana %>
      </div>
    </div>

    <div class="row">
      <div class="col-lg-3">
        <h4>Postal code</h4>
      </div>
      <div class="col-lg-9">
        〒 <%= @customer.post_code %>
      </div>
    </div>

    <div class="row">
      <div class="col-lg-3">
        <h4>Street address</h4>
      </div>
      <div class="col-lg-9">
        <%= @customer.address %>
      </div>
    </div>

    <div class="row">
      <div class="col-lg-3">
        <h4>phone number</h4>
      </div>
      <div class="col-lg-9">
        <%= @customer.tel %>
      </div>
    </div>

    <div class="row">
      <div class="col-lg-3">
        <h4>Email</h4>
      </div>
      <div class="col-lg-9">
        <%= @customer.email %>
      </div>
    </div>
  </div>

  <!--Other links-->
  <div class="container space">
    <div class="row">
      <div class="col-lg-3">
        <h4>Shipping address</h4>
      </div>
      <div class="col-lg-9">
        <%= link_to 'View list', addresses_path, class: 'btn btn-danger' %>
      </div>
    </div>

    <div class="row">
      <div class="col-lg-3">
        <h4>Order history</h4>
      </div>
      <div class="col-lg-9">
        <%= link_to 'View list', orders_path, class: 'btn btn-danger' %>
      </div>
    </div>
  </div>
</div>

Withdrawal confirmation

html:app/views/customers/withdraw.html.erb


<div class="col-lg-10 offset-lg-1 space">
  <div class="row space">
    <h2>Do you really want to unsubscribe?</h2>
  </div>

  <div class="row space">
    <h4>When you withdraw from the membership, membership registration information and
      <br>You will not be able to view your purchase history.
      <br>To unsubscribe, click "Unsubscribe".
    </h4>
  </div>

  <div class="row space">
    <%= link_to "Do not withdraw",customer_path(current_customer),class: "btn btn-danger" %>
    <%= link_to "Withdraw", customer_withdraw_done_path(current_customer), method: :put, "data-confirm" => "Do you really want to unsubscribe?", class: "btn btn-danger" %>
  </div>
</div>

SCSS

app/assets/stylesheets/application.scss


// initialize
*{
  margin:0;
  padding:0;
  box-sizing:border-box;
  color: #120136;
}

a{
  text-decoration: none;
}

.space {
  padding: 50px 0 30px;
}

Postscript

This time, the function itself is not difficult, but it took a lot of time to make the screen responsive. I plan to change the buttons to the theme color later, and for now, I've made them all red. Because it stands out. Also, the link I wrote in the View file works for the time being, but since I haven't written anything on the page I jumped to, I just get the wording "Find me in ..." in the example.

By making the main screen, it finally looks like a site. There are still many features, but we will implement them in the future. As I proceeded with the IK ● A color that I was curious about, I began to think, "Isn't this an ant?" Maybe you're just used to it.

I believe that if you post a photo, it will surely become a bakery site. Continue to next time!

reference

Flash message using Twitter Bootstrap in Rails

This is convenient when you cannot come up with a suitable name or address when registering data. "Fumizuki Taro" doesn't taste good, so ... Japanese name automatic generator Random Japanese Place Name Generator

Recommended Posts

Create an EC site with Rails5 ⑤ ~ Customer model ~
Create an EC site with Rails5 ⑦ ~ Address, Genre model ~
Create an EC site with Rails 5 ⑩ ~ Create an order function ~
Create an EC site with Rails 5 ⑨ ~ Create a cart function ~
Create an EC site with Rails5 ④ ~ Header and footer ~
Create an EC site with Rails5 ⑥ ~ seed data input ~
Create an EC site with Rails5 ③-Set model associations and other things-
Create an EC site with Rails5 ② ~ Bootstrap4 settings, Controller / action definition ~
Create an EC site using stripe! (Account creation)
[Rails] Create an application
Create a Service with an empty model Liferay 7.0 / DXP
[Rails] EC site cart function
[Rails] Create an email sending function with ActionMailer (complete version)
Create an immutable class with JAVA
Create portfolio with rails + postgres sql
Create an app with Spring Boot 2
[Rails] DB design for EC site
Create pagination function with Rails Kaminari
Create an excel file with poi
Create an app with Spring Boot
Create My Page with Rails devise
Create an app catalog site using CLI for Microsoft 365 with Docker
[Rails] Create an evaluation function using raty.js
Let's create an instance with .new yourself. .. ..
Create an infinite scroll with Infinite Scroll and kaminari
[Java] Create an executable module with Gradle
[Rails6] Create a new app with Rails [Beginner]
Easy deployment with Capistrano + AWS (EC2) + Rails
Create Rails 6 + MySQL environment with Docker compose
[Rails withdrawal] Create a simple withdrawal function with rails
[Rails 5] Create a new app with Rails [Beginner]
Make a site template easily with Rails
[Ruby on Rails] Model test with RSpec
Create an or search function with Ransack.
Let's make an error screen with Rails
Nuxt.js × Create an application in Rails API mode
Downgrade an existing app created with rails 5.2.4 to 5.1.6
[Rails] rails new to create a database with PostgreSQL
Create an RSA encryption-enabled JSON API with wicket
Create a team chat with Rails Action Cable
Rails6.0 ~ How to create an eco-friendly development environment
Create an Annotator that uses kuromoji with NLP4J [007]
How to create member variables with JPA Model
[Swift] Create an image selection UI with PhotoKit
[Rails] How to build an environment with Docker
[Rails] Model Association (Association)
How to push an app developed with Rails to Github
Create an HTTPS file server for development with ring-jetty-adapter
How to make an almost static page with rails
Create an E2E test environment with Docker x Cypress
Create a simple demo site with Spring Security with Spring Boot 2.1
[Rails] Create initial data with seed.rb [Faker] [Japanese localization]