Series Hướng Dẫn Lập Trình Ruby on Rails (Phần 6)
Bài đăng này đã không được cập nhật trong 3 năm
Chào các bạn, hôm nay mình sẽ tiếp tục phần 6 của Series Hướng dẫn lập trình Ruby on Rails. Ở phần trước chúng ta đã hoàn thành các chức năng sau đây:
-
Cho phép đăng ký mới một
User
. -
Login
với thông tinUser
đã đăng ký. -
Logout
sau khiLogin
thành công.Ở chức năng Login chúng ta đã có sử dụng
session
để lưu thông tinUser
cụ thể ở đây làuser.id
nó được viết ở đây nếu bạn nào quên :
app/helpers/sessions_helper.rb
module SessionsHelper
def log_in user
session[:user_id] = user.id
end
def log_out
session.delete :user_id
end
end
Như vậy tạm thời sau khi chúng ta login
session[:user_id] sẽ lưu id
của User mà chúng ta đăng nhập, và lúc logout
session[:user_id] sẽ bị delete đi
Tiếp theo chúng ta sẽ viết hàm để kiểm tra trước mỗi lần User muốn truy cập một địa chỉ nào cũng phải kiểm tra user
đó đã login
hay chưa, nếu đã login
thì cho phép truy cập, ngược lại sẽ redirect đến Login Page
để buộc phải đăng nhập trước khi muốn truy cập bất cứ trang nào.
Chúng ta sẽ viết hàm kiểm tra xem user
đã đăng nhập hay chưa, hàm này sẽ dùng chung và sau này sẽ gọi lại nhiều lần nên hãy đưa nó vào SessionsHelper
Sau khi đăng nhập việc lấy thông tin user
hiện tại là cần thiết, nên ta sẽ viết luôn hàm current_user
để lấy thông tin user hiện tại
app/heplers/sessions_helper.rb
# GET current_user
def current_user
@current_user ||= User.find_by id: session[:user_id]
end
# Check user has logged in before ?
def logged_in?
current_user.present?
end
Tiếp theo chúng ta sẽ kiểm tra nếu user đã đăng nhập hay chưa, theo mặc đinh các Controller được tạo ra đều kế thừa từ ApplicationController
nên ta sẽ viết hàm filter
ở đây, và nó sẽ có tác dụng đối với tất cả các Controller con kế thừa từ nó.
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include SessionsHelper
before_action :require_login
def require_login
unless logged_in?
redirect_to login_path
end
end
end
Trông có vẻ ok rồi đấy nhỉ, bật rails s
lên vào vào thử http://localhost:3000/users
xem nó có yêu cầu đăng nhập không nhé (nhớ logout trước :v)
Kết quả là không chạy được, có vẻ chúng ta đã bỏ qua một điều gì đó.
Vì chúng ta viết hàm require_login ở ApplicationController nên nó ảnh hướng đến tất cả các Controller kế thừa nó phải không nào,
trong đó có cả SessionsController < ApplicationController, do đó khi gọi redirect_to login_path
sẽ gọi action #new của
SessionsController và sẽ lại chạy hàm require_login
một lần nữa, cứ như vậy tạo ra vòng lặp vô hạn.
Do đó chúng ta cần phải bỏ qua hàm require_login
đối với action #new, #create của SessionsController. Ta sẽ có như này
class SessionsController < ApplicationController
skip_before_action :require_login, only: [:new, :create]
.
.
.
end
OK thử truy cập lần nữa vào http://localhost:3000/users
xem nó có redirect về trang Login không nào.
Có vẻ ok rồi đấy nhỉ
Ta sẽ tút tát lại cho các trang một chút nhé :
Hiển thị tất cả users hiện tại sau khi login thành công
app/controllers/users_controller.rb
class UsersController < ApplicationController
def index
@users = User.all
end
.
.
.
end
app/views/users/index.html.erb
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h1 class="title">LOGIN APP</h1>
</div>
<div class="col-lg-12 form-group">
<label for="">Welcome</label>
<%= link_to current_user.name, user_path(current_user) %>
</div>
<div class="col-lg-12 form-group">
<label for="">List Users</label>
<table class="table">
<thead>
<th>ID</th>
<th>User Name</th>
</thead>
<tbody>
<%= render @users %>
</tbody>
</table>
</div>
</div>
</div>
app/views/users/_user.html.erb
<div class="container">
<div class="row">
<div class="col-lg-offset-3 col-lg-6">
<div class="text-left col-lg-6", style="padding-left: 0px ">
<label>User name: <%= @user.name %></label>
</div>
<div class="text-right col-lg-6">
<%= link_to "Logout", logout_path, method: :delete %>
</div>
</div>
<div class="col-lg-offset-3 col-lg-6">
<%= link_to "List Users", users_path %>
</div>
</div>
</div>
app/views/users/show.html.erb
<div class="container">
<div class="row">
<div class="col-lg-offset-3 col-lg-6">
<div class="text-left col-lg-6", style="padding-left: 0px ">
<label>User name: <%= @user.name %></label>
</div>
<div class="text-right col-lg-6">
<%= link_to "Logout", logout_path, method: :delete %>
</div>
</div>
<div class="col-lg-offset-3 col-lg-6">
<%= link_to "List Users", users_path %>
</div>
</div>
</div>
Các bạn có thể check lại một lượt thử logout
truy cập vào link http://localhost:3000/users
nó sẽ redirect đến trang login, yêu cầu đăng nhập
sau khi login các bạn tắt tab và truy cập vào lại link trên xem, nó vào thẳng luôn và hiện tên đang nhập là mọi thứ có vẻ ok rồi đấy :v
OK, như vậy đến đây demo login_app nhỏ đã hoàn thành,
Kì tiếp theo mình sẽ giới thiệu đến các bạn các kỹ thuật khác của Rails: nested_attributes, association : has_many, has_one, belongs_to,.. validates trong Model, I18n, thiết lập file Settings,...sử dụng các loại gem thông dụng Cancancan, Devise, Kaminari, carrierwave,... Hẹn gặp lại các bạn trong kỳ tới (bow)
All rights reserved