代碼比較簡單:
module?ActionController?#:nodoc:
??class?CheckGroupError?<?ActionControllerError?#:nodoc:
????attr_reader?:group_name
????def?initialize(group_name)
??????@group_name?=?group_name
????end
??end
??
??class?CheckRoleError?<?ActionControllerError?#:nodoc:
????attr_reader?:role_name
????def?initialize(role_name)
??????@role_name?=?role_name
????end
??end
??
??class?Base?#:nodoc:
????def?roles
??????[]
????end
????
????def?groups
??????[]
????end
????
????def?check_roles(*role_args)
??????role_args.each?do?|role|
????????check_role(role)
??????end
????end
????
????def?check_groups(*group_args)
??????group_args.each?do?|group|
????????check_group(group)
??????end
????end
????
????def?check_group(group)
??????raise?CheckGroupError.new(group.to_s)?unless?groups().include?(group.to_s)
????end
????
????def?check_role(role)
??????raise?CheckRoleError.new(role.to_s)???unless?roles().include?(role.to_s)??????
????end
??end
??
end
只需要在ApplicationController中實現roles和groups這2個方法,對數據庫模式沒有任何限制,只要能保證這2個方法能夠得到當前用戶的角色和組即可。
有4個check方法可用,可任意使用一個或多個。
簡單模擬測試一下:
class?ApplicationController?<?ActionController::Base
??def?roles
????%w(add?show)
??end
??def?groups
????%w(users)
??end
end
class?TestController?<?ApplicationController
??def?test1
????check_role?:add
????render_text?"OK"
??end
??def?test2
????check_role?:add
????check_group?:users
????render_text?"OK"
??end
??def?test3
????check_groups?:admin,?:users
????render_text?"OK"
??end
??def?test4
????check_roles?:add,?:remove
????render_text?"OK"
??end
end
其中,test1、test2都會成功,而test3和test4則會失敗顯示異常,只需要處理rescue_action把它修改為自己的顯示頁面即可。