Sha256: efdcaa4b1afb771f20d50f620017940c4091c40d4c1e002a2a15c253065e5fed

Contents?: true

Size: 1.58 KB

Versions: 3

Compression:

Stored size: 1.58 KB

Contents

module MagickColumns
  module ActiveRecord
    def has_magick_columns(options = {})
      @@_magick_columns ||= {}
      @@_magick_columns[name] ||= []

      options.each do |field, type|
        column_options = _magick_column_options(type)

        @@_magick_columns[name] << { field: field }.merge(column_options)
      end
    end

    def magick_search(query)
      or_queries = []
      terms = {}

      MagickColumns::Tokenizer.new(query).extract_terms.each_with_index do |or_term, i|
        and_queries = []

        or_term.each_with_index do |and_term, j|
          mini_query = []

          @@_magick_columns[name].each_with_index do |column, k|
            if column[:condition].call(and_term[:term])
              operator = and_term[:operator] || _map_magick_column_operator(column[:operator])
              terms[:"t_#{i}_#{j}_#{k}"] = column[:mask] % {t: and_term[:term]}

              mini_query << "#{column[:field]} #{operator} :t_#{i}_#{j}_#{k}"
            end
          end

          and_queries << mini_query.join(' OR ')
        end

        or_queries << and_queries.map { |a_q| "(#{a_q})" }.join(' AND ')
      end

      where(or_queries.map { |o_q| "(#{o_q})" }.join(' OR '), terms)
    end

    private

    def _magick_column_options(type)
      type.kind_of?(Hash) ? type : MagickColumns::DEFAULTS[type.to_sym]
    end

    def _map_magick_column_operator(operator, db = nil)
      db ||= ::ActiveRecord::Base.connection.adapter_name

      operator == :like ? (db == 'PostgreSQL' ? 'ILIKE' : 'LIKE') : operator
    end
  end
end

ActiveRecord::Base.extend MagickColumns::ActiveRecord

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
magick_columns-0.0.4 lib/magick_columns/active_record.rb
magick_columns-0.0.3 lib/magick_columns/active_record.rb
magick_columns-0.0.2 lib/magick_columns/active_record.rb