Монгоидный вопрос о синтаксисе - PullRequest
0 голосов
/ 06 июня 2011

В эпизоде ​​189 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 ]

4 голосов
/ 07 июня 2011

Этот эпизод Railscasts действительно был разработан для баз данных, которые не поддерживают массивы как нативные типы (что делает Mongoid).Затем вы можете просто создать область, которая использует один из критериев запроса массива .

Например:

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"), причем последние возвращают пользователей, которые являются модераторами или авторами.

0 голосов
/ 25 октября 2014

Вы можете использовать нативную карту уменьшения механизма mongoDB, которая открывается через mongoid с помощью метода 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

Это даст области видимости в виде:

User.admins
User.moderators
User.authors
...