Ruby on rails ActiveRecord在同一型号上有多个且属于

Ruby on rails ActiveRecord在同一型号上有多个且属于,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我已经研究过这个问题,但我仍然难以理解这个概念 我对链接的SO问题也有类似的设置,因为我有一个User类,它包含员工和经理。我还为角色(保留角色名称)和用户角色(保留哪个用户拥有哪个角色)提供了另一个模型 我的要求规定,一名员工(其角色为用户的用户只能有一名经理(其角色为经理的用户的)。现在,这个管理概念是对当前系统的一个补充,我不应该更改用户表,所以我正在用他们自己的MVC创建一个新表 但是现在我发现很难使用有很多和属于,就像链接的问题一样。我如何使用新型号?我试着使用:通过,但它不起作用(出

我已经研究过这个问题,但我仍然难以理解这个概念

我对链接的SO问题也有类似的设置,因为我有一个
User
类,它包含员工和经理。我还为
角色
(保留角色名称)和
用户角色
(保留哪个用户拥有哪个角色)提供了另一个模型

我的要求规定,一名员工(其
角色为
用户的
用户只能有一名经理(其
角色为
经理的
用户的
)。现在,这个管理概念是对当前系统的一个补充,我不应该更改
用户
表,所以我正在用他们自己的MVC创建一个新表

但是现在我发现很难使用
有很多
属于
,就像链接的问题一样。我如何使用新型号?我试着使用
:通过
,但它不起作用(出于某种原因)

我做错了吗?我是否应该在
用户
中添加一个
manager\u id
列,并将链接问题中的解决方案加入到我的问题中?此外,如何确保只有
角色为
经理的
用户
可以设置为经理

注意:我必须说,我对Rails和ActiveRecord,甚至对Ruby都是比较陌生的

注2:如果相关的话,我使用的是Rails 4.2.0。

类用户class User < ActiveRecord::Base
  belongs_to :manager, class_name: 'User'
  has_many :employees, foreign_key: :manager_id, class_name: 'User'
end
属于:经理,类别名称:“用户” 有很多:员工,外键::经理id,类名:'User' 结束
有帮助吗

更新:

class User < ActiveRecord::Base
  has_one :role, through: :user_role
  belongs_to :manager, -> { where(role: {name: 'manager'}), class_name: 'User'
  has_many :employees, -> { where(role: {name: 'employee'}), foreign_key: :manager_id, class_name: 'User'
end
class用户{其中(角色:{name:'manager'}),类_-name:'User'
有多个:employees,->{where(角色:{name:'employeer'}),外键::经理id,类名:'User'
结束

设置具有角色的多对多系统非常简单:

class User
  has_many :user_roles
  has_many :roles, through: :user_roles

  def has_role?(role)
    roles.where(name: role).any?
  end
end

class Role
  has_many :user_roles
  has_many :users, through: :user_roles
end

class UserRole
  belongs_to :role
  belongs_to :user
  validates_uniqueness_of :role, :user
end
只需确保在UserRole上为role和user创建唯一索引:

add_index :user_roles, [:role_id, :user_id], unique: true
实现manager需求最简单、最有效的方法是添加
manager\u id
列到
users
并设置自引用一对多关系:

class User
  has_many :user_roles
  has_many :roles, through: :user_roles

  belongs_to :manager, class_name: 'User'
  has_many :subordinates, foreign_key: :manager_id, class_name: 'User'

  validate :authorize_manager!

  def has_role?(role)
    roles.where(name: role).any?
  end

  private
  def authorize_manager!
    if manager.present?
    errors.add(:manager, "does not have manager role") unless manager.has_role?("manager") 
    end
  end
end
另一种方法是使用资源范围的角色。 最好的部分是你没有自己构建它。有一个由社区创建的优秀的宝石,名为,它为你建立了一个系统

它也比以前的系统更加灵活,一旦你掌握了窍门,你就可以在你的领域中的任何资源中添加角色

class User < ActiveRecord::Base
  rolify
  resourcify
end

---

the_boss = User.find(1)
bob = User.find_by(name: 'Bob')

# creating roles
the_boss.add_role(:manager) # add a global role
the_boss.add_role(:manager, bob) # add a role scoped to a user instance

# querying roles
bob.has_role?(:manager) # => false 
the_boss.has_role?(:manager) # => true
the_boss.has_role?(:manager, bob) # => true
the_boss.has_role?(:manager, User.create) # => false
class用户false
_boss.have_role?(:manager)#=>true
_boss.have_role?(:经理,鲍勃)#=>对
_boss.has_role?(:manager,User.create)#=>false

如果您使用Rolify,请使用授权库(如Pundit或CanCanCan)来执行规则。

这是链接问题的解决方案,但我无法使其工作。我如何将新表引入关联?此更新如何?不确定这是您试图实现的,但您可能应该看看嗯,所以我应该/必须在
users
表中添加一个
manager\u id
列?这取决于你想做什么,但是如果你想将一个用户链接到另一个用户,而这个用户将是他同一类的父用户,那么使用像这样的外键是一个好方法。我不应该编辑
users
表,但是,如果另一个选项是添加另一个gem,也许一个新的列不是一个坏主意。我想我使用的是
manager\u id
列。如何在错误消息中获取新插入的管理器的名称?编辑:无需担心,我发现
manager.name
“添加另一个gem”这并不总是一件坏事。不要因为担心技术部门或非发明者综合症而重新发明轮子。这尤其适用于身份验证和授权。这就是人们被黑客攻击的原因。