Module: FullSearch::Callbacks

Defined in:
lib/full_search/callbacks.rb

Class Method Summary collapse

Class Method Details

.associated_class(model, association_name) ⇒ Object



76
77
78
79
# File 'lib/full_search/callbacks.rb', line 76

def self.associated_class(model, association_name)
  reflection = model.reflect_on_association(association_name.to_sym)
  reflection&.klass
end

.association_key(model, association_name) ⇒ Object



81
82
83
84
# File 'lib/full_search/callbacks.rb', line 81

def self.association_key(model, association_name)
  reflection = model.reflect_on_association(association_name.to_sym)
  reflection&.foreign_key&.to_s || "#{association_name}_id"
end

.install!(model) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/full_search/callbacks.rb', line 5

def self.install!(model)
  dsl = model.full_search_dsl

  source_fields = dsl.fields.select(&:source)
  return if source_fields.empty?

  model.after_save do
    FullSearch::Callbacks.reindex_record!(self)
  end

  model.after_destroy do
    FullSearch::Callbacks.remove_record!(self)
  end

  dsl.fields.each do |field|
    next unless field.reindex_on

    assoc_class = associated_class(model, field.reindex_on)
    assoc_class&.after_save do |record|
      FullSearch::Callbacks.reindex_dependents!(record, model, field)
    end
    assoc_class&.after_destroy do |record|
      FullSearch::Callbacks.reindex_dependents!(record, model, field)
    end
  end
end

.reindex_dependents!(parent_record, dependent_model, field) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/full_search/callbacks.rb', line 61

def self.reindex_dependents!(parent_record, dependent_model, field)
  fk = association_key(dependent_model, field.reindex_on)
  sql = "SELECT id FROM #{dependent_model.table_name} WHERE #{fk} = #{parent_record.id}"
  dependent_ids = ActiveRecord::Base.connection.execute(sql).map { |r| r["id"] }

  dependent_ids.each do |dep_id|
    if field.async
      FullSearch::ReindexJob.perform_later(dependent_model.name, dep_id, field.name)
    else
      dependent = dependent_model.find_by(id: dep_id)
      reindex_field!(dependent, field.name) if dependent
    end
  end
end

.reindex_field!(record, field_name) ⇒ Object



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

def self.reindex_field!(record, field_name)
  dsl = record.class.full_search_dsl
  field = dsl.fields.find { |f| f.name == field_name }
  return unless field&.source

  value = record.instance_exec(&field.source)
  table = FullSearch::Index.fts_table_name(record.class)
  quoted_value = ActiveRecord::Base.connection.quote(value.to_s)
  ActiveRecord::Base.connection.execute(
    "UPDATE #{table} SET #{field.name} = #{quoted_value} WHERE rowid = #{record.id}"
  )
end

.reindex_record!(record) ⇒ Object



32
33
34
35
36
37
38
39
40
41
# File 'lib/full_search/callbacks.rb', line 32

def self.reindex_record!(record)
  dsl = record.class.full_search_dsl
  return unless dsl

  dsl.fields.each do |field|
    next unless field.source

    reindex_field!(record, field.name)
  end
end

.remove_record!(record) ⇒ Object



56
57
58
59
# File 'lib/full_search/callbacks.rb', line 56

def self.remove_record!(record)
  table = FullSearch::Index.fts_table_name(record.class)
  ActiveRecord::Base.connection.execute("DELETE FROM #{table} WHERE rowid = #{record.id}")
end