使用关注点扩展具有角色的用户模型

Posted

技术标签:

【中文标题】使用关注点扩展具有角色的用户模型【英文标题】:Using Concerns to Extend User Model With Roles 【发布时间】:2016-05-30 19:43:13 【问题描述】:

我正在尝试在 Rails 中使用 Concerns 和特定于角色的方法构建基于角色的数据结构。我探索了其他解决方案,例如 STI、多态关联,但选择尝试这种方法。

所有描述的属性都存储在一个表中,用户。

module Client
   extend ActiveSupport::Concern

   def self.extended(target)
     target.class_eval do
         validates :emergency_contact, presence: true
     end
   end
end

module Doctor
   def self.extended(target)
     target.class_eval do
         validates :credentials, presence: true  
     end
   end
end

class User < ApplicationRecord
   validates :role, allow_blank: true, inclusion:  in: roles 
   validates :first_name, presence: true
   validates :last_name, presence: true
   validates :email, presence: true

   after_initialize  extend_role 

   # Extend self with role-appropriate Concern
   def extend_role
      extend role.camelize.constantize if role
   end

   def role=(role)
      super(role)
      extend_role
   end
end

我的挑战是在角色更改期间,具体来说,可以做些什么(如果有的话)来否定前一个角色对扩展用户的关注?

每个用户将拥有 1 个角色,因此将客户和医生的问题都混入用户是不合适的(至少目前是这样)。

在理想的解决方案中,用户实例会随着角色的变化而变形并保留所有变化的属性。

所以,这样称呼:

user.update_attributes( first_name: 'Wily', last_name: 'McDoc', role: 'doctor' )

...将首先处理角色更改,然后更新属性。

【问题讨论】:

您可能需要考虑使用多表继承。 github.com/hzamani/acts_as_relation 虽然这可行,但实际上您只是通过 mixins 进行单表继承 - 您仍然拥有 STI 的所有缺点。 @max 这里的部分想法是使其易于扩展为多个角色,而 STI 不是。我不确定 active_record-acts_as 是否能适应,我会研究一下,但一个简单的本土解决方案似乎很理想。 【参考方案1】:

猜测可以部分删除所有方法:

Module.instance_methods.each|m|
  undef_method(m)

另外,How can I reverse ruby's include function,以防万一

【讨论】:

谢谢,但这行不通。我无法完全删除被覆盖的方法。

以上是关于使用关注点扩展具有角色的用户模型的主要内容,如果未能解决你的问题,请参考以下文章

Laravel - 我有一个具有不同角色的用户模型。如何在具有特定角色的用户之间建立关系? [关闭]

性能测试时需要关注哪些性能

具有额外多对多关系的 JPA 多对多

rails模型的影子表

建立团队的性能文化

MySQL 8.0 ROLE管理