Sha256: e8f3675612cc8c2dc105411ceae3948f4563003ad5b91ab3db3e9e4a92609d29

Contents?: true

Size: 1.38 KB

Versions: 2

Compression:

Stored size: 1.38 KB

Contents

require "bitroles/version"

module Bitroles
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def has_roles(*args)
      if args.any?
        roles_mask = 'roles_mask'
        if args.last.is_a?(Hash)
          options = args.pop if args.last.is_a?(Hash)
          roles_mask = options[:mask_column].to_s
        end
        roles = args.map(&:to_s)

        roles.each do |role|
          class_eval <<-EVAL, __FILE__, __LINE__
            scope :with_role, -> role { where(["#{roles_mask} & ? > 0", 2**#{roles}.index(role.to_s)]) }

            def is_#{role}?
              role? role
            end

            def #{role}=(val)
              if val
                self.roles += [#{role}] unless has_role? #{role}
              else
                self.roles -= [#{role}] if has_role? #{role}
              end
            end
          EVAL
        end

        class_eval <<-EVAL, __FILE__, __LINE__
          def roles=(roles)
            roles = (roles.map(&:to_s) & #{roles}).map { |r| 2**#{roles}.index(r) }.sum
            self.#{roles_mask} = roles
          end

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

          def has_role?(role)
            roles.include? role.to_s
          end
        EVAL
      end
    end
  end
end

class ActiveRecord::Base
  include Bitroles
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
bitroles-0.1.1 lib/bitroles.rb
bitroles-0.1.0 lib/bitroles.rb