1

Ich habe eine Klasse User und ein paar Klassen für Benutzerrollen genannt (zB Admin, Contributor, Member), die bilden die User Klasse erben:Mehrere rollenbasierte Klassen von User-Klasse geerbt - Rails 4

class Admin < User; end 

nach dem STI Prinzip sind roles als jsonb in der Benutzer-Tabelle gespeichert, wie so:

t.jsonb :roles, default: { 
    'admin':  false, 
    'contributor': false, 
    'member':  true 
    } 

Ist es möglich, die entsprechende Unterklasse t einstellen o eine Instanz eines User für die entsprechende Rolle. Mit anderen Worten, so etwas wie:

u = User.create(...) 
u.class #<= returns 'User' 
u.grant_role(admin) 
u.class #<= should return 'Admin' 

Ich denke einen before_save Rückruf verwenden, so dass jedes Mal User Instanz instanziiert oder aktualisiert wird, wird eine entsprechende Klasse ausgewählt. Bin ich auf dem richtigen Weg?

Antwort

1

Ich denke nicht, dass es möglich ist, den Typ einer Instanz im laufenden Betrieb zu ändern, aber ich bin mir nicht 100% sicher, wenn man bedenkt, dass wir hier über Ruby sprechen. :)

Anstatt STI, die die Klasse User ändert, wie wäre es mit der strategy pattern?

Haben Sie einen Satz RoleStrategy Klassen, die je nach Wert von instanziiert werden.

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 

Das Verhalten ändern würde automatisch je nachdem, was der Wert von role ist:

Für Ihren Fall könnte es so etwas wie diese.