Rails – Filter

4.6/5 - (13 votes)

Filter là các phương thức chạy trước, sau hoặc cùng với một phương thức action (phương thức của controller).

Các phương thức filter có tính thừa kế, tức là nếu chúng ta gọi các phương thức filter trong lớp ApplicationController, thì các lớp kế thừa nó cũng chạy các phương thức filter đó.

Trong phần này chúng ta sẽ sử dụng filter để chặn truy cập vào trang /admin/index nếu người dùng chưa đăng nhập.

Đầu tiên chúng ta sửa lại lớp ApplicationController như sau:

class ApplicationController < ActionController::Base
    # Prevent CSRF attacks by raising an exception.
    # For APIs, you may want to use :null_session instead.
    before_filter :authorize
 
    protect_from_forgery with: :exception
 
  private
   
    def current_cart
        Cart.find(session[:cart_id])
            rescue ActiveRecord::RecordNotFound
            cart = Cart.create
            session[:cart_id] = cart.id
        cart
    end
 
    helper_method :current_cart
 
  protected
 
    def authorize
        @user = User.find_by_id(session[:user_id]) 
        if @user == nil
            redirect_to '/login', :notice => 'You must login first'
        end
    end
end

Filter có 3 loại là before, afteraround, tương ứng với chạy trước, sau hoặc chạy cùng.

Ở đây chúng ta dùng phương thức before_filter, và truyền vào tham số :authorize, đây là phương thức kiểm tra xem người dùng có đăng nhập hay chưa do chúng ta tự định nghĩa. Nếu người dùng chưa đăng nhập thì chúng ta cho trỏ tới trang /login.

Phương thức authorize sẽ chạy trước các phương thức action khác, tuy nhiên có một vấn đề, như đã nói ở trên là các filter sẽ được thừa kế, tức là các lớp controller con cũng sẽ chạy dòng before_filter ở trên. Trong số các controller kế thừa có cả controller chịu trách nhiệm việc hiển thị trang /login, tức là ở đây chúng ta không cho người dùng đăng nhập luôn.

Để giải quyết việc này thì chúng ta dùng các phương thức skip, ví dụ chúng ta thêm dòng này vào đầu lớp SessionsController như sau:

class SessionsController < ApplicationController
    skip_before_filter :authorize
    .
    .
    .
end

Có thể hiểu phương thức skip_before_filter :authorize sẽ đưa phương thức authorize vào danh sách “đen”, tức là không được chạy. Và do đó chúng ta có thể chạy các phương thức khác bình thường.

Và không chỉ có lớp SessionsController mà tất cả các lớp controller con khác cũng cần được “mở khóa” nữa. Chúng ta lần lượt sửa lại như sau:

Lớp StoreController:

class StoreController < ApplicationController
    skip_before_filter :authorize
    .
    .
    .
end

Lớp CartsController:

class CartsController < ApplicationController
    skip_before_filter :authorize, :only => [:create, :update, :destroy]
    .
    .
    .
end

Chúng ta có thể truyền vào tham số :only, tham số này sẽ quy định chỉ có một số phương thức nhất định được “mở khóa”.

Lớp LineItemsController:

class LineItemsController < ApplicationController
    skip_before_filter :authorize, :only => :create
    .
    .
    .
end

Lớp OrdersController:

class OrdersController < ApplicationController
    skip_before_filter :authorize, :only => [:new, :create]
    .
    .
    .
end

Vậy là xong, bây giờ nếu chúng ta vào trang /admin/index hay một số trang nhất định mà chưa đăng nhập thì chúng ta sẽ được trỏ về trang /login.

Bạn có thể tìm hiểu thêm về các phương thức filter tại đây.

0 0 votes
Article Rating
Subscribe
Thông báo cho tôi qua email khi
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 Comments
Inline Feedbacks
View all comments
Anh
Anh
6 năm trước

undefined method `before_filter’ for ApplicationController:Class Did you mean? before_action ad cho hỏi lỗi này với

Anh
Anh
6 năm trước

before_filter va before_action la 1 nhi ad