首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Ruby on Rails 開發從頭來(十七):使用 Filter 控制存取權限

     編輯:Java 相關知識

Filter 機制簡介

Rails 控制器提供三種過濾器,可在動作執行前/後/環繞插入邏輯:

  • before_filter:動作前執行,回傳 false 或 render/redirect 可中斷後續流程
  • after_filter:動作後執行
  • around_filter:包裹動作執行(較少用)

實作管理員授權

ApplicationController 定義授權方法

class ApplicationController < ActionController::Base
  def authorize
    unless session[:user_id]
      flash[:notice] = "Please log in"
      redirect_to :controller => "login", :action => "login"
    end
  end
end

AdminController 套用過濾器

class AdminController < ApplicationController
  before_filter :authorize
  # 所有動作執行前先檢查登入
  
  def index; end
  def list; end
  def ship; end
  # ...
end

LoginController 排除登入動作

class LoginController < ApplicationController
  before_filter :authorize, :except => :login
  # login 動作不檢查授權,避免無限迴圈
  
  def login; end
  def logout; end
  def add_user; end
  # ...
end

使用者管理功能

用戶列表

# login_controller.rb
def list_users
  @all_users = User.find(:all)
end

# views/login/list_users.rhtml
<% @page_title = "User List" -%>

<% for user in @all_users -%>
  
<% end -%>
<%= user.name %> <%= link_to("(delete)", :action => :delete_user, :id => user.id) %>

保護特定用戶不被刪除

# user.rb
before_destroy :dont_destroy_dahuzizyd

def dont_destroy_dahuzizyd
  raise "Can't destroy dahuzizyd" if self.name == 'dahuzizyd'
end

# login_controller.rb
def delete_user
  id = params[:id]
  if id && user = User.find(id)
    begin
      user.destroy
      flash[:notice] = "User #{user.name} deleted"
    rescue
      flash[:notice] = "Can't delete that user"
    end
  end
  redirect_to :action => :list_users
end

模型回呼 before_destroy 拋出例外,控制器捕獲並轉為友善提示。

動態佈局:登入後顯示管理選單

# views/layouts/admin.rhtml


  ADMINISTER Pragprog Books Online Store
  <%= stylesheet_link_tag "scaffold", "depot", "admin", :media => "all" %>


  
  
<% if session[:user_id] -%> <%= link_to("Products", :controller => "admin", :action => "list") %>
<%= link_to("Shipping", :controller => "admin", :action => "ship") %>

<%= link_to("Add user", :controller => "login", :action => "add_user") %>
<%= link_to("List users", :controller => "login", :action => "list_users") %>

<%= link_to("Log out", :controller => "login", :action => "logout") %> <% end -%>
<% if flash[:notice] -%>
<%= flash[:notice] %>
<% end -%> <%= @content_for_layout %>

登出實作

def logout
  session[:user_id] = nil
  flash[:notice] = "Logged out"
  redirect_to :action => "login"
end

重構:集中購物車存取

# store_controller.rb
before_filter :find_cart, :except => :index

def find_cart
  @cart = (session[:cart] ||= Cart.new)
end

# 移除各動作中重複的 @cart = find_cart

使用 before_filter 集中處理共同前置邏輯,乾淨符合 DRY 原則。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved