2009-05-26 6 views
26

Je suis juste en train d'apprendre ruby ​​sur rails et j'ai une table des rôles utilisateur (propriétaire, administrateur et utilisateur). Il y aura des endroits dans le code où je dois vérifier le rôle de l'utilisateur et montrer différentes options. Est-ce que quelqu'un sait comment faire cela sans recourir à des chiffres magiques ou d'autres méthodes laides?Rails Types énumérés ou alternatives

Dans des applications web ASP.Net j'ai travaillé je l'ai vu ceci fait par l'utilisation des types énumérés:

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

// ... 

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

Chaque rôle différent dans la base de données se reflète comme un type énuméré avec une valeur défini sur l'ID de ce rôle dans la base de données. Cela ne semble pas être une très bonne solution, car cela dépend de la connaissance de la base de données qui peut changer. Même si c'est la bonne façon de gérer quelque chose comme ça, je ne sais pas comment utiliser les types énumérés dans les rails.

J'apprécierais tout aperçu de cette question.

Répondre

26

Ruby lui-même ne dispose pas d'un type énuméré, mais ce site montre une méthode http://www.rubyfleebie.com/enumerations-and-ruby/

Vous pourriez faire quelque chose comme ça dans votre modèle utilisateur:

#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

Je préfère utiliser le bien nommé Authorization plugin pour des situations comme celle-ci.

Cela vous permettra de

permit "role" 

de restreindre l'accès aux rôles et

permit? "role" 

simplement test pour l'accès. Ces deux délégués à User#has_role?(role). Ne vous sentez pas comme vous devez utiliser leur implémentation ObjectRoles

Vous pouvez utiliser les rôles Hardwired puis implémenter votre propre méthode User#has_role?(role) pour utiliser votre schéma existant.

+0

En outre, Bates Ryan a un bon petit bijou d'autorisation appelé cancan et un tutoriel bien sur son site (http://railscasts.com/episodes/192 -authorisation-avec-cancan) –

0

Il y a un enum plugin sur rubyforge si vous faites:

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

Il est assez laid d'utiliser :limit attribut pour transmettre des paramètres, mais il est d'une manière plus standardisée.

Pour installer il suffit de faire:

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

il fonctionne currenctly avec Rails 2.2.2 ou version ultérieure. Rubyforge lien: www.rubyforge.org/projects/enum-column/

4

Cela semble être un très bon cas pour l'utilisation de ma gemme classy_enum. Il vous permet essentiellement de définir un ensemble fixe d'options, où chacune est une classe avec un comportement et des propriétés spécifiques. Il aide à réduire toute la logique conditionnelle qui a tendance à se disperser dans l'application.

Par exemple, si vous faites des choses comme ceci:

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

ensuite appeler comme: user.options un autre endroit ...

classy_enum vous permet de déplacer cette logique à un endroit séparé et ont la même fonctionnalité sans logique conditionnelle:

class User < ActiveRecord::Base 
    classy_enum_attr :role 

    delegate :options, :to => :role 
end 

Le README a un exemple de travail et décrit en détail la pierre précieuse.

2

Juste commencer à apprendre Rails (à partir de C#), et avait exactement la même question. Il semble que Rails n'a pas vraiment d'enums parce que la philosophie est différente. J'utiliserais des tonnes d'enums pour essayer d'organiser tous les détails dans un projet C#, mais peut-être que Rails gère tellement pour vous qu'ils ne sont pas si importants. Ce n'est pas vraiment une réponse, juste une observation.

12

La fonctionnalité ajoutée dans Rails 4.1 pourrait-elle être ce que vous cherchez?

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

Copie du blog:

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