menu

Rails - Authentification (prepare database)


Kembali lagi di Ruby on Rails,

Pada tutorial sebelumnya kita sudah belajar membuat sebuah sistem CRUD (delete). Kali ini kita akan belajar yang agak sedikit rumit yaitu membuat sebuah sistem login dan logout atau biasa disebut sistem authentification.

Tutorial ini akan di sajikan dalam beberapa step karena akan sangat panjang jika hanya dipraktekkan pada satu page tutorial saja. Pada step yang pertama ini akan lebih menitik beratkan pada persiapan database login yang akan digunakan.

Oke langsung saja kita mulai tutorialnya,

Pertama, tambahkan gem bcrypt pada file Gemfile seperti ini,
source 'https://rubygems.org'

gem 'rails',        '5.0.0.1'
gem 'puma',         '3.4.0'
gem 'sass-rails',   '5.0.6'
gem 'uglifier',     '3.0.0'
#gem 'coffee-rails', '4.2.1'
gem 'jquery-rails', '4.1.1'
gem 'turbolinks',   '5.0.1'
gem 'jbuilder',     '2.4.1'

group :development, :test do
  gem 'sqlite3', '1.3.11'
  gem 'byebug',  '9.0.0', platform: :mri
end

group :development do
  gem 'web-console',           '3.1.1'
  gem 'listen',                '3.0.8'
  gem 'spring',                '1.7.2'
  gem 'spring-watcher-listen', '2.0.0'
  gem 'bcrypt',                '3.1.7'
end

group :production do
  gem 'pg', '0.18.4'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
dan jangan lupa untuk mengcompilenya dengan cara ketikkan pada terminal "bundle install"

Selanjutnya, tambahkan dua field baru yaitu email dan password_digest pada file migrate (tanggal_create_users.rb) yang terletak pada path db/migrate/ sehingga code akan tampak seperti ini,
class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
        t.string :first_name
        t.string :last_name
        t.string :nick_name
        t.text :address
        t.integer :phone
        t.string :email
        t.string :password_digest
        t.date :birth_date
        t.timestamps
    end
  end
end

Kemudian, edit pula file seeds.rb pada path db/ untuk menyesuaikan dengan file migrate yang sudah dibuat, sehingga code seedsnya akan tampak seperti ini,
User.create!([
  { first_name: "Monkey", last_name: "D Garp", nick_name: "Garp", address: "East Blue", phone: 8111, email: "monkey@mail.com", password: "password", password_confirmation: "password", birth_date: DateTime.parse("01/01/1991") },
  { first_name: "John", last_name: "Wick", nick_name: "Wick", address: "New York", phone: 8112, email: "jhon@mail.com", password: "password", password_confirmation: "password", birth_date: DateTime.parse("02/02/1992") },
  { first_name: "Dracule", last_name: "Mihawk", nick_name: "Mihawk", address: "West Blue", phone: 8113, email: "dracule@mail.com", password: "password", password_confirmation: "password", birth_date: DateTime.parse("03/03/1993") },
])

Jangan lupa tambahkan aturan penulisan password dengan menambahkan code pada file model user.rb pada path app/models/ edit menjadi seperti ini,
class User < ApplicationRecord
 has_secure_password
end

Setelah itu, buka terminal kembali, dan dan ketikkan code berikut
#roleback atau hapus database
rake db:roleback
#migrate atau create database
rake db:migrate
#seed atau isi field database
rake db:seed

Untuk mengecek databasenya ketikkan pada terminal "rails console" setelah masuk ke sqlnya ketikkan "User.all" maka akan tampil, tampilan seperti ini,


yang berarti migration dan seedernya berhasil karena bertambah dua field baru yaitu email dan password_digest.

Selanjutnya tambahkan permit baru untuk field email dan password dengan edit controller user_controller.rb pada path app/controllers/ menjadi seperti ini,
class UsersController < ApplicationController
 def index
  @users = User.all
 end

 def _signup
  @user = User.new
 end

 def _addUser 
   @user = User.new(user_params) 
   if @user.save
     redirect_to '/login' 
   else 
     redirect_to '/' 
   end 
 end

 def _show
  @user = User.find(params[:id])
 end

 def _edit
  @user = User.find(params[:id])
  if @user.update(user_params)
   redirect_to '/users' 
  else 
   redirect_to '/' 
  end 
 end

 def _delete
  @user = User.find(params[:id])
  if @user.destroy
   redirect_to '/users' 
  else 
   redirect_to '/' 
  end 
 end

 private
  def user_params
   params.require(:user).permit(:first_name, :last_name, :nick_name, :address, :phone, :email, :password)
  end
end

Kemudian edit view file index.html.erb pada path app/views/users/ menjadi seperti ini,
<%= provide(:title, "User") %>
<h1>Table user</h1>
<br>
<table border="1px" width="100%">
 <thead>
  <tr>
   <th>No</th>
   <th>Name</th>
   <th>Nick Name</th>
   <th>Address</th>
   <th>Phone number</th>
   <th>Email</th>
   <th>Birthdate</th>
   <th>Action</th>
  </tr>
 </thead>
 <tbody>
  <% no=1; @users.each do |x| %>
  <% if !x.first_name then x.first_name='' end; if !x.last_name then x.last_name='' end %>
   <tr>
    <td><%= no %></td>
    <td><%= x.first_name+' '+x.last_name %></td>
    <td><%= x.nick_name %></td>
    <td><%= x.address %></td>
    <td><%= x.phone %></td>
    <td><%= x.email %></td>
    <td><%= x.birth_date %></td>
    <td><%= link_to "Edit", user_path(x) %> || <%= link_to 'Delete',  { action: :_delete, id: x.id }, method: :delete, data: { confirm: 'Are you sure?' } %></td>
   </tr>
  <% no+=1; end %>
 </tbody>
</table>

Setelah itu edit pula view _signup.html.erb pada path app/views/users/ menjadi seperti ini,
<%= provide(:title, "Sign Up") %>
<div class="text-center">
 <h1>Sign up</h1>
 <br><br>
 <div class="form-group">
  <%= form_for(@user, url: {action: "_addUser"}, method: "post") do |f| %>
     <%= f.text_field :first_name, :placeholder => "First name", class: 'form-input', required: true %><br>
     <%= f.text_field :last_name, :placeholder => "Last name", class: 'form-input', required: true %><br>
     <%= f.text_field :nick_name, :placeholder => "Nick name", class: 'form-input', required: true %><br>
     <%= f.text_area :address, :placeholder => "Address", class: 'form-input-textarea', required: true %><br>
     <%= f.number_field :phone, :placeholder => "Phone number", class: 'form-input', required: true %><br>
     <%= f.email_field :email, :placeholder => "Email", class: 'form-input', required: true %><br>
     <%= f.password_field :password, :placeholder => "Password", class: 'form-input', required: true %><br>
   <div class="left-float">
    <%= f.submit "Create an account", class: "btn-submit" %>
   </div>
     <div class="right-float">
      <!--input type="button" name="login" value="Login" class="btn-submit"-->
   </div>
  <% end %>
 </div>
</div>
<br>

Terakhir edit view _show.html.erb pada path app/views/users/ menjadi seperti ini,
<%= provide(:title, "Edit") %>
<h1>Edit User</h1>
<br>
<div class="form-group">
 <%= form_for(@user, url: {action: "_edit"}, method: "post") do |f| %>
  <label>First Name</label>
    <%= f.text_field :first_name, :value => @user.first_name, class: 'form-input', required: true %><br>
    <label>Last Name</label>
    <%= f.text_field :last_name, :value => @user.last_name, class: 'form-input', required: true %><br>
    <label>Nick Name</label>
    <%= f.text_field :nick_name, :value => @user.nick_name, class: 'form-input', required: true %><br>
    <label>Address</label>
    <%= f.text_area :address, :value => @user.address, class: 'form-input-textarea', required: true %><br>
    <label>Phone</label>
    <%= f.number_field :phone, :value => @user.phone, class: 'form-input', required: true %><br>
    <%= f.email_field :email, :value => @user.email, class: 'form-input', required: true %><br>
    <%= f.password_field :password, :value => @user.password, class: 'form-input', required: true %><br>
  <%= f.submit "Save", class: "btn-submit" %>  <input type="button" onclick="location.href='/users';" value="Cancel" class="btn-submit" />
 <% end %>
</div>

Sehingga salah satu tampilan viewnya akan berubah seperti ini,


===DONE!===