class FuzzyWhere::FuzzyRelationBuilder

Class to build and {ActiveRecord_Relation} based on fuzzy conditions

Attributes

relation[R]

@!attribute [r] relation

@return [ActiveRecord_Relation] the current standard query

Public Class Methods

new(table, relation, conditions) click to toggle source

New FuzzyRelationBuilder intance @param table [String] table name @param relation [ActiveRecord_Relation] query to append @param conditions [Hash] fuzzy conditions

# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 29
def initialize(table, relation, conditions)
  @table = table
  @conditions = conditions
  @relation = relation
  @calibration = calibration
  @membership_degrees = []
end
sqlite3?() click to toggle source

Is sqlite3 validation

# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 10
def sqlite3?
  active_record_adapter == 'sqlite3'.freeze
end

Private Class Methods

active_record_adapter() click to toggle source

ActiveRecord adapter

# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 17
def active_record_adapter
  ActiveRecord::Base.connection.instance_values['config'][:adapter]
end

Public Instance Methods

build() click to toggle source

Build an ActiveRecord relation based on fuzzy conditions

@return [ActiveRecord_Relation] the final standard query

# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 40
def build
  process_conditions
  add_membership_column
  add_calibration_column
  order_by_membership_degree
end

Private Instance Methods

add_calibration_column() click to toggle source
# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 95
def add_calibration_column
  @relation = @relation.where("(#{membership_degree}) >= ?", @calibration)
end
add_membership_column() click to toggle source
# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 89
def add_membership_column
  name = FuzzyWhere.config.membership_degree_column_name
  @relation = @relation
              .select("#{@table}.*, (#{membership_degree}) AS #{name}")
end
calibration() click to toggle source
# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 49
def calibration
  @calibration = @conditions.delete(FuzzyWhere.config.calibration_name)
  @calibration ||= 0.5
  validate_calibration
end
derivate_condition(column, pred_def) click to toggle source
# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 77
def derivate_condition(column, pred_def)
  FuzzyDerivation.new(@relation, @table, column, pred_def)
    .derivative_condition
end
load_fuzzy_predicate_definition(predicate) click to toggle source
# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 71
def load_fuzzy_predicate_definition(predicate)
  pred_def = FuzzyWhere.config.fuzzy_predicate(predicate)
  fail FuzzyError, "couldn't find fuzzy definition" unless pred_def
  pred_def
end
membership_degree() click to toggle source
# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 99
def membership_degree
  if @membership_degrees.size > 1
    min_membership_degree
  else
    @membership_degrees.first
  end
end
membership_degree_function(column, pred_def) click to toggle source
# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 82
def membership_degree_function(column, pred_def)
  membership_degree = PredicateMembershipDegree.new(@table,
                                                    column,
                                                    pred_def)
  @membership_degrees << membership_degree.membership_function
end
min_membership_degree() click to toggle source

Use apropiate SQL method for minimun value

# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 108
def min_membership_degree
  if FuzzyRelationBuilder.sqlite3?
    "MIN(#{@membership_degrees.join(',')})"
  else
    "LEAST(#{@membership_degrees.join(',')})"
  end
end
order_by_membership_degree() click to toggle source
# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 116
def order_by_membership_degree
  name = FuzzyWhere.config.membership_degree_column_name
  @relation.order("#{name} DESC")
end
process_conditions() click to toggle source
# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 62
def process_conditions
  @conditions.each do |column, predicate|
    pred_def = load_fuzzy_predicate_definition(predicate)
    @relation = derivate_condition(column, pred_def)
    membership_degree_function(column, pred_def)
  end
  @relation
end
validate_calibration() click to toggle source
# File lib/fuzzy_where/fuzzy_relation_builder.rb, line 55
def validate_calibration
  Float @calibration
rescue
  raise ArgumentError,
        "calibration must be a Float, got #{@calibration.inspect}"
end