2009-05-26 9 views
26

Ich lerne gerade Ruby on Rails und ich habe eine Tabelle von Benutzerrollen (Besitzer, Admin und Benutzer). Es werden Stellen im Code sein, an denen ich die Rolle des Benutzers überprüfen und verschiedene Optionen anzeigen muss. Weiß jemand, wie man das macht, ohne auf magische Zahlen oder andere hässliche Methoden zurückzugreifen? Rails aufgezählte Typen oder Alternativen

In ASP.Net-Web-Apps Ich habe auf die ich gearbeitet habe dies durch die Verwendung von Aufzählungstypen getan gesehen:

public enum UserRole { Owner = 1, Admin = 2, User = 3 } 

// ... 

if (user.Role == UserRole.Admin) 
    // Show special admin options 

Jede andere Rolle in der Datenbank als Aufzählungstyp mit einem Wert widerspiegelt Legen Sie die ID dieser Rolle in der Datenbank fest. Das scheint keine sehr gute Lösung zu sein, da es auf Datenbankwissen ankommt, das sich ändern kann. Auch wenn es der richtige Weg ist, um so etwas zu handhaben, weiß ich nicht, wie man aufgezählte Typen in Schienen benutzt.

Ich würde jede Einsicht in diese Angelegenheit schätzen.

Antwort

26

Rubin selbst nicht einen Aufzählungstyp hat, aber diese Seite zeigt ein Verfahren http://www.rubyfleebie.com/enumerations-and-ruby/

Sie könnten so etwas in Ihrem User-Modell machen:

#constants 
OWNER = 1 
ADMIN = 2 
USER = 3 

def is_owner? 
    self.role == OWNER 
end 

def is_admin? 
    self.role == ADMIN 
end 

def is_user? 
    self.role == USER 
end 
2

Ich ziehe den passenden Namen verwenden Authorization Plugin für solche Situationen.

Sie für den Zugriff

permit "role" 

Zugriff auf Rollen beschränken, und

permit? "role" 

einfach Test Dies lässt. Beide delegieren an User#has_role?(role).

Haben Sie nicht das Gefühl, dass Sie ihre ObjectRoles Implementierung verwenden müssen. Sie können die Rollen Hardwired verwenden und dann Ihre eigene User#has_role?(role)-Methode implementieren, um Ihr vorhandenes Schema zu verwenden.

+0

Auch hat Ryan Bates eine gute Authorization Juwel namens Cancan und einen schönen Tutorial auf seiner Website (http://railscasts.com/episodes/192 -Autorisierung mit Cancan –

0

Es gibt eine enum plugin auf RubyForge so Sie tun:

t.column :severity, :enum, :limit => [:low, :medium, :high, :critical] 

Es ziemlich hässlich ist :limit Attribut zu verwenden, Parameter zu übergeben, aber es ist eine standardisierte Art und Weise.

einfach tun, zu installieren:

script/plugin install svn://rubyforge.org/var/svn/enum-column/plugins/enum-column 

es funktioniert currenctly mit Rails 2.2.2 oder höher. Rubyforge Link: www.rubyforge.org/projects/enum-column/

4

Dies scheint ein wirklich guter Fall für die Verwendung meiner classy_enum Edelstein. Es ermöglicht Ihnen im Wesentlichen, eine festgelegte Menge von Optionen zu definieren, wobei jede eine Klasse mit spezifischen Eigenschaften und Eigenschaften ist. Es hilft, die gesamte bedingte Logik zu reduzieren, die dazu neigt, in der gesamten Anwendung verstreut zu werden.

Zum Beispiel, wenn Sie Dinge wie dies tun:

class User < ActiveRecord::Base 
    def options 
    if user.is_admin? 
     [...admin options...] 
    else 
     [...non admin options...] 
    end 
    end 
end 

Dann wie der Aufruf: user.options woanders ...

classy_enum ermöglicht es Ihnen, diese Logik zu einem separaten Ort zu bewegen und die gleiche Funktionalität ohne bedingte Logik haben:

class User < ActiveRecord::Base 
    classy_enum_attr :role 

    delegate :options, :to => :role 
end 

Die README hat ein funktionierendes Beispiel und beschreibt den Edelstein im Detail.

2

Gerade erst zu lernen, Rails (von C#), und hatte genau diese Frage. Es scheint, dass Rails nicht wirklich Enums hat, weil die Philosophie anders ist. Ich würde Tonnen von Enums verwenden, um zu versuchen, alle Details in einem C# -Projekt zu organisieren, aber vielleicht, weil Rails so viel für Sie behandelt, sind sie nicht so wichtig. Es ist nicht wirklich eine Antwort, nur eine Beobachtung.

12

Könnte die Funktionalität in Rails 4.1 hinzugefügt werden, was Sie suchen?

http://coherence.io/blog/2013/12/17/whats-new-in-rails-4-1.html

Kopieren von Blog-Post:

class Bug < ActiveRecord::Base 
    # Relevant schema change looks like this: 
    # 
    # create_table :bugs do |t| 
    # t.column :status, :integer, default: 0 # defaults to the first value (i.e. :unverified) 
    # end 

    enum status: [ :unverified, :confirmed, :assigned, :in_progress, :resolved, :rejected, :reopened ] 

... 

Bug.resolved   # => a scope to find all resolved bugs 
bug.resolved?   # => check if bug has the status resolved 
bug.resolved!   # => update! the bug with status set to resolved 
bug.status    # => a string describing the bug's status 
bug.status = :resolved # => set the bug's status to resolved 
Verwandte Themen