Ruby on rails 员工和用户的CanCan
我有一个Ruby on rails 员工和用户的CanCan,ruby-on-rails,ruby-on-rails-3,ruby-on-rails-3.2,cancan,Ruby On Rails,Ruby On Rails 3,Ruby On Rails 3.2,Cancan,我有一个票证模型、一个员工模型和一个用户模型 用户和员工可以创建票证,但员工也可以为其分配票证。因此,user\u id是指票据的创建者,employee\u id是指指定的员工(我不确定这是否是最佳方式) 票.rb class Ticket < ActiveRecord::Base before_save :default_values after_commit :close_solved after_commit :close_canceled before_creat
票证
模型、一个员工
模型和一个用户
模型
用户和员工可以创建票证,但员工也可以为其分配票证。因此,user\u id
是指票据的创建者,employee\u id
是指指定的员工(我不确定这是否是最佳方式)
票.rb
class Ticket < ActiveRecord::Base
before_save :default_values
after_commit :close_solved
after_commit :close_canceled
before_create :assign_state
attr_accessible :description, :title, :employee_department_id, :user_id, :first_name, :last_name , :email, :state_id, :employee_id, :ticket_state, :assign_state
belongs_to :employee_department
belongs_to :user
belongs_to :state
belongs_to :employee
has_many :replies
def default_values
self.state_id = 3 if self.state_id.nil?
end
def to_label
ticket_state.to_s
end
def close_solved
if self.ticket_state == "solved"
self.update_column(:ticket_state, "closed (solved)")
self.save!
end
end
def close_canceled
if self.ticket_state == "canceled"
self.update_column(:ticket_state, "closed (canceled)")
self.save!
end
end
def assign_state
if self.employee_id.nil?
self.assign_state = "un-assigned"
else
self.assign_state = "assigned"
end
end
Ticket.all.each do |ticket|
if ticket.ticket_state.blank?
ticket.ticket_state = 'open'
end
ticket.save
end
end
票务控制员.rb
class TicketsController < ApplicationController
load_and_authorize_resource
def index
@tickets = Ticket.all
@tickets_grid = initialize_grid(Ticket, :include => [{:user => :user_type}, :employee_department, :state])
end
def show
@ticket = Ticket.find(params[:id])
@reply = @ticket.replies.build # this for comments on ticket
@state = State.all # this for a model called State which describe the priority of the ticket (Emergency / High / Normal )
end
def new
@ticket = Ticket.new
end
def create
@ticket = Ticket.new(params[:ticket])
if @ticket.save
flash[:notice] = 'Support ticket request created.'
redirect_to @ticket
else
flash[:error] = 'An error occurred please try again!'
redirect_to '/dashboard'
end
end
def edit
@ticket = Ticket.find(params[:id])
end
def update
@ticket = Ticket.find(params[:id])
if @ticket.update_attributes(params[:ticket])
flash[:notice] = 'Successfuly updated.'
redirect_to tickets_path
else
flash[:error] = 'An error occurred please try again!'
render @ticket
end
end
end
class ticketcontroller[{:用户=>:user\u type},:员工\u部门,:状态])
结束
def秀
@ticket=ticket.find(参数[:id])
@reply=@ticket.replays.build#这是关于ticket的评论
@state=state.all#这适用于描述票据优先级(紧急/高/正常)的称为state的模型
结束
def新
@票子
结束
def创建
@票证=票证。新(参数[:票证])
如果@ticket.save
flash[:notice]=“已创建支持票证请求。”
将_重定向到@ticket
其他的
flash[:error]=“出现错误,请重试!”
将_重定向到“/dashboard”
结束
结束
定义编辑
@ticket=ticket.find(参数[:id])
结束
def更新
@ticket=ticket.find(参数[:id])
if@ticket.update_属性(参数[:ticket])
flash[:notice]=“已成功更新。”
将\u重定向到票证\u路径
其他的
flash[:error]=“出现错误,请重试!”
提交@ticket
结束
结束
结束
我需要允许员工
能够管理他们分配的票据,并且我需要票据的创建者只查看他创建的票据
如何使用
CanCan
?我愿意接受其他建议,如果不能用CanCan
实现,那么使用CanCan就相当简单了。下面是一个使用您包含的能力文件的修改部分的快速示例:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
# Full access if you're the assigned employee
if user.has_role? :support_manager
can :manage, Ticket do |ticket|
ticket.try(employee) == user
end
end
# Read access only if you created the ticket
can :read, Ticket do |ticket|
ticket.try(user) == user
end
end
end
使用CanCan实现这一点相当简单。下面是一个使用您包含的能力文件的修改部分的快速示例:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
# Full access if you're the assigned employee
if user.has_role? :support_manager
can :manage, Ticket do |ticket|
ticket.try(employee) == user
end
end
# Read access only if you created the ticket
can :read, Ticket do |ticket|
ticket.try(user) == user
end
end
end
您将看到所有票据,因为在控制器内的索引操作中,您调用:
@tickets = Ticket.all
您可以尝试以下方法:
@tickets = Ticket.accessible_by(current_ability)
通过使用此方法,当前\u用户将看到当前\u用户有权访问的所有票证
更新
您可以在accessible_方法中定义特定访问权限
@tickets = Ticket.accessible_by(current_ability, :manage)
剩下的就是如何定义访问权限
定义访问权限的示例:
if user.has_role? :ticket_manager
can :manage, Ticket, employee: {:user_id => user.id}
end
您将看到所有票据,因为在控制器内的索引操作中,您调用:
@tickets = Ticket.all
您可以尝试以下方法:
@tickets = Ticket.accessible_by(current_ability)
通过使用此方法,当前\u用户将看到当前\u用户有权访问的所有票证
更新
您可以在accessible_方法中定义特定访问权限
@tickets = Ticket.accessible_by(current_ability, :manage)
剩下的就是如何定义访问权限
定义访问权限的示例:
if user.has_role? :ticket_manager
can :manage, Ticket, employee: {:user_id => user.id}
end
为了让用户能够阅读他们创建的票据,您只需要在该功能上添加一个条件(见下文)。您可以在
:create
功能上使用相同的条件,当cancan为#new
或#create
操作构建新对象时,它将为您预填充这些属性
# app/models/ticket.rb
class Ticket < ActiveRecord::Base
# <snip>
belongs_to :user
belongs_to :employee
# <snip>
end
# app/models/user.rb
class User < ActiveRecord::Base
has_one :employee
end
# app/models/ability.rb
class Ability
# <snip>
if user.has_role? :ticket_viewer
can :create, Ticket
can :read, Ticket, :user_id => user.id
end
if user.employee # && any other necessary conditions
can :create, Ticket
can :read, Ticket, :employee_id => user.employee.id
end
end
# app/controllers/tickets_controller.rb
controller TicketsController < ApplicationController
load_and_authorize_resource
def index
# @tickets = Ticket.accessible_by(current_ability) # cancan's
# load_and_authorize resource will take care of loading ticket(s) for
# all controller actions, so I've commented them out
@tickets_grid = initialize_grid(@tickets, :include => [{:user => :user_type}, :employee_department, :state])
end
def show
# @ticket = Ticket.find(params[:id])
@reply = @ticket.replies.build # this for comments on ticket
@state = State.all # this for a model called State which describe the priority of the ticket (Emergency / High / Normal )
end
def new
# @ticket = Ticket.new
end
def create
# @ticket = Ticket.new(params[:ticket])
if @ticket.save
flash[:notice] = 'Support ticket request created.'
redirect_to @ticket
else
flash[:error] = 'An error occurred please try again!'
redirect_to '/dashboard'
end
end
def edit
# @ticket = Ticket.find(params[:id])
end
def update
# @ticket = Ticket.find(params[:id])
if @ticket.update_attributes(params[:ticket])
flash[:notice] = 'Successfuly updated.'
redirect_to tickets_path
else
flash[:error] = 'An error occurred please try again!'
render @ticket
end
end
end
#app/models/ticket.rb
类票证user.id
结束
如果user.employee#&满足任何其他必要条件
can:创建,记录
can:read,Ticket,:employee\u id=>user.employee.id
结束
结束
#app/controllers/tickets\u controller.rb
控制器票证控制器<应用程序控制器
加载和授权资源
def索引
#@tickets=Ticket.accessible_by(当前能力)#cancan's
#加载和授权资源将负责加载的票证
#所有控制器操作,因此我已将其注释掉
@票证网格=初始化网格(@tickets,:include=>[{:user=>:user\u type},:employee\u department,:state])
结束
def秀
#@ticket=ticket.find(参数[:id])
@reply=@ticket.replays.build#这是关于ticket的评论
@state=state.all#这适用于描述票据优先级(紧急/高/正常)的称为state的模型
结束
def新
#@ticket=ticket.new
结束
def创建
#@ticket=ticket.new(参数[:ticket])
如果@ticket.save
flash[:notice]=“已创建支持票证请求。”
将_重定向到@ticket
其他的
flash[:error]=“出现错误,请重试!”
将_重定向到“/dashboard”
结束
结束
定义编辑
#@ticket=ticket.find(参数[:id])
结束
def更新
#@ticket=ticket.find(参数[:id])
if@ticket.update_属性(参数[:ticket])
flash[:notice]=“已成功更新。”
将\u重定向到票证\u路径
其他的
flash[:error]=“出现错误,请重试!”
提交@ticket
结束
结束
结束
为了让用户能够阅读他们创建的票据,您只需要在该功能上添加一个条件(见下文)。您可以在:create
功能上使用相同的条件,当cancan为#new
或#create
操作构建新对象时,它将为您预填充这些属性
# app/models/ticket.rb
class Ticket < ActiveRecord::Base
# <snip>
belongs_to :user
belongs_to :employee
# <snip>
end
# app/models/user.rb
class User < ActiveRecord::Base
has_one :employee
end
# app/models/ability.rb
class Ability
# <snip>
if user.has_role? :ticket_viewer
can :create, Ticket
can :read, Ticket, :user_id => user.id
end
if user.employee # && any other necessary conditions
can :create, Ticket
can :read, Ticket, :employee_id => user.employee.id
end
end
# app/controllers/tickets_controller.rb
controller TicketsController < ApplicationController
load_and_authorize_resource
def index
# @tickets = Ticket.accessible_by(current_ability) # cancan's
# load_and_authorize resource will take care of loading ticket(s) for
# all controller actions, so I've commented them out
@tickets_grid = initialize_grid(@tickets, :include => [{:user => :user_type}, :employee_department, :state])
end
def show
# @ticket = Ticket.find(params[:id])
@reply = @ticket.replies.build # this for comments on ticket
@state = State.all # this for a model called State which describe the priority of the ticket (Emergency / High / Normal )
end
def new
# @ticket = Ticket.new
end
def create
# @ticket = Ticket.new(params[:ticket])
if @ticket.save
flash[:notice] = 'Support ticket request created.'
redirect_to @ticket
else
flash[:error] = 'An error occurred please try again!'
redirect_to '/dashboard'
end
end
def edit
# @ticket = Ticket.find(params[:id])
end
def update
# @ticket = Ticket.find(params[:id])
if @ticket.update_attributes(params[:ticket])
flash[:notice] = 'Successfuly updated.'
redirect_to tickets_path
else
flash[:error] = 'An error occurred please try again!'
render @ticket
end
end
end
#app/models/ticket.rb
类票证user.id
结束
如果user.employee#&满足任何其他必要条件
can:创建,记录
can:read,Ticket,:employee\u id=>user.employee.id
结束
结束
#应用程序/控制器/票据