Sha256: 314f06108249afb878adf08fb630ebecfcb08cffb32fd973280e9e4b3a020687

Contents?: true

Size: 1.46 KB

Versions: 2

Compression:

Stored size: 1.46 KB

Contents

require 'active_support'
require 'mongoid'
require 'treetop'

module Mongoid
  module Tags
    extend ActiveSupport::Concern

    included do |base|
      field :tags, type: Array, default: []
      index tags: 1
    end

    module ClassMethods
      def selector(query)
        parser.parse(query).tap do |result|
          raise Error, parser.failure_reason unless result
        end.to_criteria
      end

      def tagged(query)
        where(tags: selector(query))
      end

    private
      def parser
        @parser ||= Treetop.load(File.expand_path('../tags.tt', __FILE__)).new
      end
    end

    class Query < Treetop::Runtime::SyntaxNode
      def to_criteria(tags = nil)
        {}.tap do |criteria|
          (tags.presence || elements).each do |tag|
            (criteria[tag.operator.selector] ||= []) << tag.to_criteria if tag.is_a? Tag

            criteria.merge!(to_criteria(tag.elements)) { |key, first, second| first + second } if tag.elements.present?
          end
        end
      end
    end

    class Tag < Treetop::Runtime::SyntaxNode
      def to_criteria
        tag.text_value
      end
    end

    class OrOperator < Treetop::Runtime::SyntaxNode
      def selector
        '$in'
      end
    end

    class AndOperator < Treetop::Runtime::SyntaxNode
      def selector
        '$all'
      end
    end

    class NotOperator < Treetop::Runtime::SyntaxNode
      def selector
        '$nin'
      end
    end

    class Error < StandardError; end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
mongoid-tags-0.3.1 lib/mongoid/tags.rb
mongoid-tags-0.3.0 lib/mongoid/tags.rb