Mongoid语法问题

时间:2011-06-06 19:36:09

标签: ruby-on-rails mongoid railscasts

episode 189 of Railscasts中,User模型中有一个命名范围,如下所示:

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

如果我尝试了许多选项并且无法使其工作,那么将如何让它在Mongoid上运行?

2 个答案:

答案 0 :(得分:4)

Railscasts的这一集真的是为那些不支持数组作为本机类型的数据库(Mongoid所做的)而设计的。然后你可以创建一个使用array query criteria之一的范围。

例如:

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

此示例允许您传入单个角色User.with_role("admin")或角色数组User.with_role("moderator", "author"),后者将返回作为主持人或作者的用户。

答案 1 :(得分:0)

您可以使用本机地图reduce mongoDB machanism,它使用for_js方法通过mongoid公开 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

这将以以下形式给出范围:

User.admins
User.moderators
User.authors