2011-06-06 5 views
0

Dans episode 189 of Railscasts, il y a un champ nommé dans le modèle de l'utilisateur qui est comme suit:MongoId Syntaxe Question

field :roles_mask,  :type => Integer 
ROLES = %w[admin moderator author] 

named_scope :with_role, lambda { |role| {:conditions => "roles_mask & #{2**ROLES.index(role.to_s)} > 0"} } 

# roles related 
def roles=(roles) 
    self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.sum 
end 

def roles 
    ROLES.reject { |r| ((roles_mask || 0) & 2**ROLES.index(r)).zero? } 
end 

def role_symbols 
    roles.map(&:to_sym) 
end 

Comment peut-on obtenir pour travailler sur MongoId comme je l'ai essayé le nombre d'options et ne pouvait pas le faire fonctionner?

Répondre

4

Cet épisode de Railscasts a été conçu pour les bases de données qui ne prennent pas en charge les tableaux en tant que types natifs (ce que fait Mongoid). Ensuite, vous pouvez simplement créer une portée qui utilise l'un des array query criteria.

Par exemple:

class User 
    include Mongoid::Document 

    field :email 
    field :roles, :type => Array 

    ROLES = %w[admin moderator author] 

    class << self 
    def with_role(*args) 
     any_in(:roles => args) 
    end 
    end 
end 

Cet exemple vous permettra de passer soit dans un seul rôle User.with_role("admin") ou un tableau de rôles User.with_role("moderator", "author"), les derniers utilisateurs de retour qui sont soit des modérateurs ou des auteurs.

+0

theTron, merci beaucoup pour la réponse, mais les rôles sont enregistrés en tant que colonne bitmask et non en tant que colonne de tableau. Je suppose que je peux me débarrasser du bitmask et le convertir en une colonne de tableau pour stocker les rôles mais je me demandais s'il y avait un moyen de faire une chose similaire que Ryan fait avec mongoid. – Miro

+1

Y a-t-il une raison pour laquelle vous utilisez le masque de bits? Le tableau finit par rendre l'implémentation beaucoup plus facile à long terme et certainement beaucoup plus lisible. – theTRON

+0

J'ai fini par utiliser des tableaux comme vous le recommandiez. Merci beaucoup. – Miro

0

Vous pouvez utiliser la carte native réduire MongoDB machanism qui est exposée à travers MongoId en utilisant la méthode de for_js http://www.rubydoc.info/github/mongoid/mongoid/Mongoid/Criteria:for_js

ROLES.each_with_index do |role, role_index| 
    scope "#{role.to_s.pluralize}", -> { self.for_js("(this.roles_mask & (1 << role_val)) > 0", role_val: role_index) } 
end 

Cela donnera champs sous forme de:

User.admins 
User.moderators 
User.authors