class Philtre::Predicates

Container for methods which return Sequel::SQL::Expression or something that can become one through Sequel.expr, eg {year: 2013}

Reminder: they're defined as methods so we can benefit from using them inside this class to define other predicates.

This can be extended in all the usual ruby ways: by including a module, reopening the class. Also using extend_with which takes a PredicateDsl block.

Constants

DefaultPredicates

Define the set of default predicates.

Public Class Methods

new( &bloc ) click to toggle source
# File lib/philtre/predicates.rb, line 11
def initialize( &bloc )
  extend_with &bloc
end

Public Instance Methods

[]( field_predicate, value, field = nil )

The main interface from Filter#to_expr

Alias for: call
call( field_predicate, value, field = nil ) click to toggle source

TODO this should probably also be method_missing? field is only used once for any given field_predicate

# File lib/philtre/predicates.rb, line 52
def call( field_predicate, value, field = nil )
  unless respond_to? field_predicate
    define_name_predicate field_predicate, value, field
  end
  send field_predicate, value
end
Also aliased as: []
extend_with( &bloc ) click to toggle source

pass a block that can contain a combination of def meth_name() or the DSL defined by PredicateDsl.

# File lib/philtre/predicates.rb, line 17
def extend_with( &bloc )
  extend PredicateDsl.new(&bloc)
end
predicate_names() click to toggle source
# File lib/philtre/predicates.rb, line 62
def predicate_names
  # ruby-2.3 no longer stores methods in order of definition. So sort by
  # longest so that we don't get false positives from shorter predicates
  # that are substrings of longer predicates, eg blank matching
  # thing_not_blank.
  DefaultPredicates.instance_methods.sort_by{|name| -name.length}
end

Protected Instance Methods

define_name_predicate( field_predicate, value, field = nil ) click to toggle source

Convert a field_predicate (field_op format), a value and a SQL field name using the set of predicates, to something convertible to a Sequel expression.

field_predicate

is a key from the parameter hash. Usually name_pred, eg birth_year_gt

value

is the value from the parameter hash. Could be a collection.

field

is the name of the SQL field to use, or nil where it would default to key without its predicate.

# File lib/philtre/predicates.rb, line 28
def define_name_predicate( field_predicate, value, field = nil )
  splitter = PredicateSplitter.new field_predicate, value

  # the default / else / fall-through is just an equality
  default_proc = ->{:eq}

  # find a better predicate, if there is one
  suffix = predicate_names.find default_proc do |suffix|
    splitter =~ suffix
  end

  # wrap the field name first, to infect the expressions so all the
  # operators work.
  field_name = Sequel.expr(field || splitter.field)

  define_singleton_method field_predicate do |value|
    send suffix, field_name, value
  end
end