我有一个名为User
的类和一些用于从Admin
类继承的用户角色(例如Contributor
,Member
,User
)的类:
class Admin < User; end
遵循STI原则,roles
在用户表格中存储为jsonb
,如下所示:
t.jsonb :roles, default: {
'admin': false,
'contributor': false,
'member': true
}
是否可以将相应的子类设置为相应角色的User
实例。换句话说,做一些像:
u = User.create(...)
u.class #<= returns 'User'
u.grant_role(admin)
u.class #<= should return 'Admin'
我正在考虑使用before_save
回调,以便每次User
实例被实例化或更新时,都会选择适当的类。我是在正确的轨道上吗?
答案 0 :(得分:1)
我认为不可能动态更改实例的类型,但我不是100%肯定这一点,考虑到我们在这里谈论Ruby。 :)
而不是正在改变User
类的STI,使用strategy pattern怎么样?
设置一组RoleStrategy
类,根据role
的值实例化。
对于你的情况,它可能是这样的:
class User
# :foo and :bar are role dependent behaviors that you want to have.
delegate :foo, :bar, to: :role_strategy
private
def role_strategy
# Need to do some error handlings here, for example, if role is nil.
"#{role.classify}RoleStrategy".constantize.new(self)
end
end
class RoleStrategy
def initialize(user)
@user = user
end
def foo
do_it
end
def bar
do_something
end
end
class AdminRoleStrategy < RoleStrategy
def bar
do_something_else
end
end
行为会自动改变,具体取决于role
的值。