在我的应用程序中实现用户角色的方便方式

时间:2016-09-26 11:58:28

标签: ruby-on-rails ruby ruby-on-rails-4

感谢阅读!

我目前正在处理我的新应用并寻找实施下一个功能的最佳方式

按照方案我需要实现“作为用户在该位置有角色”

我做了什么:

方案: 当用户向配置文件添加新位置时 其中一个需要的领域是“角色”。那可能是“客人”,“经理”或“卖家”。在模特方面完成他的最好方法是什么?

我用has_many_through assosiation

完成了这个

控制器:

def create
    @location = Location.new(location_params)
    @location.profiles << current_user.profile
    #set user role
    current_user.profile.profile_location_throughs.where(location_id: location.id).set_role(params[:location][:role])
    respond_to do |format|
      if @location.save
        ....
      end
    end
end

模型:

class Profile < ActiveRecord::Base do
  has_many :profile_location_throughs
  has_many :locations, through: :profile_location_throughs
end

class Location < ActiveRecord::Base do
  has_many :profile_location_throughs
  has_many :locations, through: :profile_location_throughs
end

class ProfileLocationThrough < ActiveRecord::Base
  # with boolean fields: manager, seller, guest

  belongs_to :location
  belongs_to :profile

  def set_role(role)
    case role
      when "guest"
        self.guest = true
      when "seller"
        self.seller = true
      when "manager"
        self.manager = true
    end
  end

end

=====

问题: 你能建议更多美丽的方式来实现他的功能吗?

1 个答案:

答案 0 :(得分:2)

有几种方法可以进行基于角色的授权。

最简单的方法是向用户自己添加enum

class Profile < ApplicationRecord
  enum role: [:guest, :seller, :manager]
end

这是非常有限的,因为它只允许&#34;全球&#34;角色。 如果您需要资源范围的角色,则需要连接表。

class Profile < ApplicationRecord
  has_many :roles
  has_many :locations, through: :roles

  def has_role?(role, location = nil)
    self.roles.exists?( { name: role, location: location}.compact )
  end

  def add_role(role, location)
    self.roles.create!( { name: role, location: location } )
  end
end

class Role < ApplicationRecord
  belongs_to :profile
  belongs_to :location
end

class Location < ApplicationRecord
  has_many :roles
  has_many :profiles, through: :roles
end

在此示例中,我们只是使用roles.name列的字符串。如果角色的种类有限,您也可以使用枚举。如果您想使用相同的角色模型(没有双关语)来区分不同类型资源上的角色,您可以使用polymorphic belongs_to relationship

class Role < ApplicationRecord
  belongs_to :profile
  belongs_to :resource, polymorphic: true
end

class Location < ApplicationRecord
  has_many :roles, as: :resource
  has_many :profiles, through: :roles
end

class OtherThing < ApplicationRecord
  has_many :roles, as: :resource
  has_many :profiles, through: :roles
end

请注意,角色只是身份验证解决方案的一部分。您可以将此与PunditCanCanCan等授权库结合使用,该授权库定义了哪些角色可以执行哪些操作以及执行这些规则的规则。