Gem 使用 Rails Task 同步 cancan's actions as permissions 到数据库中

boboism · 2012年12月08日 · 2730 次阅读

前些天看到社区中一篇 @beiersi 写的 《写一点 CanCan 结合数据库使用的简单实现》 。觉得不错,但是少了自动同步到数据库的一些实现。 后来参考了 cancan 的 wiki 《Abilities in Database》 ,写成任务来执行同步,在 jruby171 下面能用,应该 mri193 也没问题。

desc "Synchronize controllers' actions as permissions to database"
task :sync_perm => :environment do
  synchornize_controllers_actions_as_permissions_to_db
end

def synchornize_controllers_actions_as_permissions_to_db
  write_permission(:action => "manage", :subject => "all", :action_description => "All operations", :subject_description => "Everything")

  Dir.new("#{Rails.root}/app/controllers").entries.each do |controller|
    controller.camelize.gsub(".rb","").constantize.new if controller =~ /_controller/
  end
  ApplicationController.subclasses.each do |controller|
    clazz = controller.name.gsub("Controller","").singularize.understore
    actions = controller.action_methods.reject{|action| action.to_s.index("_callback")}
    write_permission(:action => "manage", :subject => clazz, :action_description => "All operations", :subject_description => clazz.camelize, :alias_actions => actions.join(","))
    actions.each do |action|
      cancan_action, action_description = eval_cancan_action(action)
      write_permission(:action => cancan_action, :subject => clazz, :action_description => action.camelize, :subject_description => clazz.camelize, :alias_actions => action)
    end
  end
end

def eval_cancan_action(action)
  case action.to_s
  when "index", "show", "search"
    cancan_action = "read"
    action_desc = I18n.t :read
  when "create", "new"
    cancan_action = "create"
    action_desc = I18n.t :create
  when "edit", "update"
    cancan_action = "update"
    action_desc = I18n.t :edit
  when "delete", "destroy"
    cancan_action = "delete"
    action_desc = I18n.t :delete
  else
    cancan_action = action.to_s
    action_desc = "Other: " << cancan_action
  end
  return cancan_action, action_desc
end

def write_permission(options={})
  options = {:action => "", :subject => "", :action_description => "", :subject_description => "", :alias_actions => ""}.merge options
  permission = Permission.where(:subject => options[:subject], :action => options[:action]).first || Permission.new
  options[:alias_actions] = Set.new((permission.alias_actions||"").split(",")|(options[:alias_actions]||"").split(",")).delete_if(&:empty?).to_a.sort.join(",")
  permission.update_attributes(options)
end
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号