Module: Knitsearch

Defined in:
lib/knitsearch.rb,
lib/knitsearch/model.rb,
lib/knitsearch/query.rb,
lib/knitsearch/engine.rb,
lib/knitsearch/version.rb,
lib/knitsearch/document.rb,
lib/knitsearch/migration.rb,
lib/knitsearch/highlighter.rb,
lib/knitsearch/levenshtein.rb,
lib/knitsearch/fuzzy_corrector.rb,
lib/knitsearch/multisearchable.rb,
lib/knitsearch/has_many_dependent.rb,
lib/knitsearch/multisearchable_sync.rb,
lib/knitsearch/has_many_through_join_dependent.rb,
lib/knitsearch/has_many_through_target_dependent.rb,
lib/generators/knitsearch/install/install_generator.rb,
lib/generators/knitsearch/multisearch_install/multisearch_install_generator.rb

Defined Under Namespace

Modules: FuzzyCorrector, HasManyDependent, HasManyThroughJoinDependent, HasManyThroughTargetDependent, Highlighter, Levenshtein, Migration, Model, Multisearchable, MultisearchableSync, Query Classes: ColumnError, ConfigurationError, Document, Engine, Error, InstallGenerator, MultisearchInstallGenerator, SchemaMismatchError, UnknownDictionaryError

Constant Summary collapse

TOKENIZER_PRESETS =
{
  unicode: "unicode61 remove_diacritics 2",
  ascii: "ascii",
  porter: "porter",
  trigram: "trigram"
}.freeze
WEIGHT_BUCKETS =
{
  "A" => 8,
  "B" => 4,
  "C" => 2,
  "D" => 1
}.freeze
SUPPORTED_DICTIONARIES =
%w[simple english trigram].freeze
VERSION =
"0.1.1"

Class Method Summary collapse

Class Method Details

.belongs_to_dependentsObject



44
45
46
# File 'lib/knitsearch.rb', line 44

def belongs_to_dependents
  @belongs_to_dependents ||= Hash.new { |h, k| h[k] = [] }
end

.has_many_dependentsObject



48
49
50
# File 'lib/knitsearch.rb', line 48

def has_many_dependents
  @has_many_dependents ||= Hash.new { |h, k| h[k] = [] }
end

.has_many_through_dependentsObject



52
53
54
# File 'lib/knitsearch.rb', line 52

def has_many_through_dependents
  @has_many_through_dependents ||= Hash.new { |h, k| h[k] = [] }
end

.has_many_through_target_dependentsObject



56
57
58
# File 'lib/knitsearch.rb', line 56

def has_many_through_target_dependents
  @has_many_through_target_dependents ||= Hash.new { |h, k| h[k] = [] }
end

.multisearch(query, limit: nil) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/knitsearch.rb', line 60

def multisearch(query, limit: nil)
  return Document.none if query.blank?

  escaped = Knitsearch::Query.escape(query, operator: :and, prefix: false, match: :word)
  return Document.none if escaped.nil?

  relation = Document
    .joins("INNER JOIN knitsearches_fts ON knitsearches_fts.rowid = knitsearches.id")
    .where("knitsearches_fts MATCH ?", escaped)
    .order(Arel.sql("bm25(knitsearches_fts)"))

  limit ? relation.limit(limit) : relation
end

.register_belongs_to_dependent(parent_class, child_class, foreign_key, shadow_map) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/knitsearch.rb', line 74

def register_belongs_to_dependent(parent_class, child_class, foreign_key, shadow_map)
  belongs_to_dependents[parent_class] << {
    model: child_class,
    foreign_key: foreign_key,
    columns: shadow_map
  }

  # Install after_update_commit hook on parent class (idempotent)
  unless parent_class.instance_variable_defined?(:@knitsearch_dependents_installed)
    parent_class.instance_variable_set(:@knitsearch_dependents_installed, true)
    parent_class.after_update_commit :knitsearch_cascade_to_children
  end
end

.register_has_many_dependent(child_class, parent_class, inverse_fk, shadow_map, parent_assoc) ⇒ Object



88
89
90
91
92
93
94
95
96
97
# File 'lib/knitsearch.rb', line 88

def register_has_many_dependent(child_class, parent_class, inverse_fk, shadow_map, parent_assoc)
  has_many_dependents[child_class] << {
    parent: parent_class,
    inverse_fk: inverse_fk,
    columns: shadow_map,
    parent_assoc: parent_assoc
  }

  child_class.include(HasManyDependent) unless child_class.include?(HasManyDependent)
end

.register_has_many_through_dependent(join_class:, target_class:, parent_class:, parent_fk:, target_fk:, parent_assoc:, shadow_map:) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/knitsearch.rb', line 99

def register_has_many_through_dependent(join_class:, target_class:, parent_class:, parent_fk:, target_fk:, parent_assoc:, shadow_map:)
  # Store on join class side (for join create/destroy callbacks)
  has_many_through_dependents[join_class] << {
    parent_class: parent_class,
    parent_fk: parent_fk,
    target_class: target_class,
    target_fk: target_fk,
    parent_assoc: parent_assoc,
    columns: shadow_map
  }

  # Store on target class side (for target update callbacks)
  source_columns = shadow_map.values
  has_many_through_target_dependents[target_class] << {
    join_class: join_class,
    parent_class: parent_class,
    parent_fk: parent_fk,
    target_fk: target_fk,
    parent_assoc: parent_assoc,
    columns: shadow_map,
    source_columns: source_columns
  }

  # Install callbacks on both join and target classes
  join_class.include(HasManyThroughJoinDependent) unless join_class.include?(HasManyThroughJoinDependent)
  target_class.include(HasManyThroughTargetDependent) unless target_class.include?(HasManyThroughTargetDependent)
end