Class: FullSearch::Dsl

Inherits:
Object
  • Object
show all
Defined in:
lib/full_search/dsl.rb

Defined Under Namespace

Classes: ExactMatch, Field, Filter, RankBy

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model_class) ⇒ Dsl

Returns a new instance of Dsl.



12
13
14
15
16
17
18
19
20
# File 'lib/full_search/dsl.rb', line 12

def initialize(model_class)
  @model_class = model_class
  @fields = []
  @exact_matches = []
  @filters = []
  @rank_bys = []
  @tokenize = FullSearch.config.default_tokenizer
  @soft_delete_column = nil
end

Instance Attribute Details

#exact_matchesObject (readonly)

Returns the value of attribute exact_matches.



5
6
7
# File 'lib/full_search/dsl.rb', line 5

def exact_matches
  @exact_matches
end

#fieldsObject (readonly)

Returns the value of attribute fields.



5
6
7
# File 'lib/full_search/dsl.rb', line 5

def fields
  @fields
end

#filtersObject (readonly)

Returns the value of attribute filters.



5
6
7
# File 'lib/full_search/dsl.rb', line 5

def filters
  @filters
end

#highlight_configObject (readonly)

Returns the value of attribute highlight_config.



5
6
7
# File 'lib/full_search/dsl.rb', line 5

def highlight_config
  @highlight_config
end

#model_classObject (readonly)

Returns the value of attribute model_class.



5
6
7
# File 'lib/full_search/dsl.rb', line 5

def model_class
  @model_class
end

#rank_bysObject (readonly)

Returns the value of attribute rank_bys.



5
6
7
# File 'lib/full_search/dsl.rb', line 5

def rank_bys
  @rank_bys
end

Instance Method Details

#config_hashObject



100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/full_search/dsl.rb', line 100

def config_hash
  require "digest"
  Digest::SHA256.hexdigest([
    model_class.table_name,
    tokenize,
    soft_delete_column,
    typo_tolerance?,
    typo_tolerance_min_term_length,
    fields.map { |f| [f.name, f.weight, f.source.nil? ? "column" : "proc:#{f.version}", f.reindex_on, f.async, f.as] },
    exact_matches.map { |e| [e.name, "proc:#{e.version}"] },
    filters.map { |f| [f.name, f.required] },
    rank_bys.map { |r| [r.column, r.direction] }
  ].inspect)
end

#exact_match(name, source: -> { public_send(name) }, version: nil) ⇒ Object

Raises:



35
36
37
38
39
40
41
42
# File 'lib/full_search/dsl.rb', line 35

def exact_match(name, source: -> { public_send(name) }, version: nil)
  unless valid_name?(name)
    raise InvalidFieldError, "#{model_class.name}: invalid exact_match name #{name.inspect}"
  end
  str = name.to_s
  raise InvalidFieldError, "#{model_class.name}: duplicate exact_match name #{name.inspect}" if exact_matches.any? { |e| e.name == str }
  @exact_matches << ExactMatch.new(name: str, source: source, version: version)
end

#field(name, weight: 1, source: nil, reindex_on: nil, async: FullSearch.config.default_async_reindex, as: nil, version: nil) ⇒ Object

Raises:



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/full_search/dsl.rb', line 22

def field(name, weight: 1, source: nil, reindex_on: nil, async: FullSearch.config.default_async_reindex, as: nil, version: nil)
  unless valid_name?(name)
    raise InvalidFieldError, "#{model_class.name}: invalid field name #{name.inspect}"
  end
  if as && !valid_name?(as)
    raise InvalidFieldError, "#{model_class.name}: invalid field alias (as): #{as.inspect}"
  end
  str = name.to_s
  raise InvalidFieldError, "#{model_class.name}: duplicate field name #{name.inspect}" if fields.any? { |f| f.name == str }
  raise InvalidFieldError, "#{model_class.name}: field name #{name.inspect} conflicts with existing filter" if filters.any? { |f| f.name == str }
  @fields << Field.new(name: str, weight: weight.to_i, source: source, reindex_on: reindex_on&.to_s, async: async, as: as&.to_s, version: version)
end

#filter(name, required: false) ⇒ Object

Raises:



57
58
59
60
61
62
63
64
65
# File 'lib/full_search/dsl.rb', line 57

def filter(name, required: false)
  unless valid_name?(name)
    raise InvalidFieldError, "#{model_class.name}: invalid filter name #{name.inspect}"
  end
  str = name.to_s
  raise InvalidFieldError, "#{model_class.name}: duplicate filter name #{name.inspect}" if filters.any? { |f| f.name == str }
  raise InvalidFieldError, "#{model_class.name}: filter name #{name.inspect} conflicts with existing field" if fields.any? { |f| f.name == str }
  @filters << Filter.new(name: str, required: required)
end

#highlight(open_tag: "<mark>", close_tag: "</mark>") ⇒ Object



83
84
85
# File 'lib/full_search/dsl.rb', line 83

def highlight(open_tag: "<mark>", close_tag: "</mark>")
  @highlight_config = {open_tag: open_tag, close_tag: close_tag}
end

#rank_by(column, direction = :desc) ⇒ Object

Raises:



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/full_search/dsl.rb', line 44

def rank_by(column, direction = :desc)
  unless valid_name?(column)
    raise InvalidFieldError, "#{model_class.name}: invalid rank_by column #{column.inspect}"
  end
  dir = direction.to_s.downcase
  unless %w[asc desc].include?(dir)
    raise InvalidFieldError, "#{model_class.name}: invalid rank_by direction #{direction.inspect}. Use :asc or :desc."
  end
  str = column.to_s
  raise InvalidFieldError, "#{model_class.name}: duplicate rank_by column #{column.inspect}" if rank_bys.any? { |r| r.column == str }
  @rank_bys << RankBy.new(column: str, direction: dir.to_sym)
end

#soft_delete_column(name = :_no_arg_) ⇒ Object



67
68
69
70
71
72
73
# File 'lib/full_search/dsl.rb', line 67

def soft_delete_column(name = :_no_arg_)
  if name == :_no_arg_
    @soft_delete_column
  else
    @soft_delete_column = name.to_s
  end
end

#tokenize(value = :_no_arg_) ⇒ Object



75
76
77
78
79
80
81
# File 'lib/full_search/dsl.rb', line 75

def tokenize(value = :_no_arg_)
  if value == :_no_arg_
    @tokenize
  else
    @tokenize = Tokenizer.validate!(value)
  end
end

#typo_tolerance(enabled = true, min_term_length: nil) ⇒ Object



87
88
89
90
# File 'lib/full_search/dsl.rb', line 87

def typo_tolerance(enabled = true, min_term_length: nil)
  @typo_tolerance = enabled
  @typo_tolerance_min_term_length = min_term_length || 3
end

#typo_tolerance?Boolean

Returns:

  • (Boolean)


92
93
94
# File 'lib/full_search/dsl.rb', line 92

def typo_tolerance?
  !!@typo_tolerance
end

#typo_tolerance_min_term_lengthObject



96
97
98
# File 'lib/full_search/dsl.rb', line 96

def typo_tolerance_min_term_length
  @typo_tolerance_min_term_length || 3
end