【问题标题】:Rails & Rolify: Add default role on creation?Rails & Rolify:在创建时添加默认角色?
【发布时间】:2012-07-03 14:22:55
【问题描述】:

目前我正在使用 Rolify & CanCan 来管理我的 Rails 3 应用程序中的角色和能力。我的问题是:如何让用户在创建时默认拥有一个角色?例如,如果我有一个“用户”角色,¿我怎样才能让在我的应用中注册的所有用户默认都有一个 user 角色?我的 Ability.rb 有这个代码:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.has_role? :admin
      can :manage, :all
    elsif user.has_role? :user
      can :update, User, :id => user.id
    end
  end
end

我的用户模型有这个:

class User < ActiveRecord::Base
  rolify
  authenticates_with_sorcery!
  attr_accessible :username, :email, :password, :password_confirmation

  validates_confirmation_of :password
  validates_presence_of :password, :on => :create
  validates_presence_of :username
  validates_uniqueness_of :username
  validates_presence_of :email
  validates_uniqueness_of :email
end

榜样这个:

class Role < ActiveRecord::Base
  has_and_belongs_to_many :users, :join_table => :users_roles
  belongs_to :resource, :polymorphic => true
end

UsersController 我们有:

def new
  @user = User.new
end

def create
  @user = User.new(params[:user])

  if @user.save
    redirect_to users_path, :notice => "Tu usuario se ha guardado"
  else
    render "new"
  end
end

Rolify Migration终于是这个了:

class RolifyCreateRoles < ActiveRecord::Migration
  def change
    create_table(:roles) do |t|
      t.string :name
      t.references :resource, :polymorphic => true

      t.timestamps
    end

    create_table(:users_roles, :id => false) do |t|
      t.references :user
      t.references :role
    end

    add_index(:roles, :name)
    add_index(:roles, [ :name, :resource_type, :resource_id ])
    add_index(:users_roles, [ :user_id, :role_id ])
  end
end

现在,我可以使用 rails 控制台手动分配角色:

1 User.all
2 User.find(id)
3 User.add_role(:role)

但是如何在每个用户创建默认角色时自动分配默认角色?

谢谢!

【问题讨论】:

    标签: ruby-on-rails authorization roles


    【解决方案1】:

    您可以在创建用户后使用active record callback 分配角色。类似的东西

    class User < ActiveRecord::Base
      after_create :assign_default_role
    
      def assign_default_role
        add_role(:role)
      end
    end
    

    请注意,还有一个 after_save 回调,但每次保存用户时都会调用它。因此,如果您编辑用户并保存它会尝试再次添加角色。这就是我改用after_create 回调的原因。

    【讨论】:

    • 这也是一个很好的解决方案! ;)
    • 太棒了!救了我很多的悲伤。
    • 你最好检查一下add_role之前是否分配了角色
    • @CamSong 但这是一个 after_create 回调,因此无需检查。
    【解决方案2】:

    您最好在 add_role 之前检查是否分配了角色。所以我更喜欢:

    class User < ActiveRecord::Base
      after_create :assign_default_role
    
      def assign_default_role
        add_role(:normal) if self.roles.blank?
      end
    end
    

    【讨论】:

    • 这是after_create,不应有任何其他角色。
    【解决方案3】:

    算了,顺便补充一下:

    @user.add_role(:user)
    

    @user = User.new(params[:user]) 行之后的创建操作中。

    我自己想出来的......我还在学习:)

    谢谢!

    【讨论】:

    • 您在控制器中执行此操作,这是错误的操作位置。像这样的逻辑应该进入模型。俗话说“瘦控,胖模特”。在模型中这样做还可以让您进行单元测试而不是控制器测试。
    • Dty 有道理。你希望它是干燥的。任何创建用户的控制器/动作都必须有这行代码。通过使用 after_create 回调将其放入模型中,您可以将其 DRY。
    • 为什么不把它放在迁移中呢?类似于: def change change_column :users, :role, :integer, :default => 'user' end 然后,当使用 devise 创建用户时,默认情况下它成为角色 'user'。
    【解决方案4】:
    after_create :default_role
    
    private
      def default_role
        self.roles << Role.find_by_name("user")
        self.save
      end
    

    【讨论】:

      猜你喜欢
      • 2017-04-24
      • 1970-01-01
      • 2021-03-09
      • 1970-01-01
      • 1970-01-01
      • 2016-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多