Class: Runestone::Model

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/runestone/model.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#highlightsObject

Returns the value of attribute highlights.



5
6
7
# File 'lib/runestone/model.rb', line 5

def highlights
  @highlights
end

Class Method Details

.get_binds(hash, highlight) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/runestone/model.rb', line 70

def self.get_binds(hash, highlight)
  rt = []
  highlight.each do |k, v|
    next unless hash[k]

    if hash[k].is_a?(Hash)
      rt += get_binds(hash[k], highlight[k])
    elsif hash[k].is_a?(Array)
      hash[k].each do |i|
        if i.is_a?(Hash)
          rt += get_binds(i, highlight[k])
        else
          rt += i.is_a?(Array) ? i : [i]
        end
      end
    else
      rt << hash[k].to_s
    end
  end
  rt
end

.get_highlights(words, query, prefix: nil, dictionary: nil) ⇒ Object



60
61
62
63
64
65
66
67
68
# File 'lib/runestone/model.rb', line 60

def self.get_highlights(words, query, prefix: nil, dictionary: nil)
  dictionary ||= Runestone.dictionary
  
  query = Arel::Nodes::TSQuery.new(Runestone::WebSearch.parse(query, prefix: prefix).typos.synonymize.to_s, language: dictionary).to_sql
  connection.exec_query(<<-SQL).cast_values
    SELECT ts_headline(#{connection.quote(dictionary)}, words, #{query}, 'ShortWord=2')
    FROM unnest(ARRAY[ #{words.map{ |t| connection.quote(t) }.join(', ')} ]::varchar[]) AS words
  SQL
end

.highlight(records, query, prefix: nil) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/runestone/model.rb', line 9

def self.highlight(records, query, prefix: nil)
  return [] if records.empty?
  
  binds = []
  records.each do |record|
    binds += get_binds(record.data, record.record_type.constantize.highlights(dictionary: records.first.dictionary))
  end

  hlites = binds.uniq

  newbinds = []
  binds.each_with_index do |b|
    newbinds << hlites.index(b)
  end
  binds = newbinds

  hlites = get_highlights(hlites, query, prefix: prefix, dictionary: records.first.dictionary)

  binds.map! { |x| hlites[x] }

  records.each do |record|
    record.highlights = highlight_data(
      record.data,
      binds,
      record.record_type.constantize.highlights
    )
  end
end

.highlight_data(data, hlights, indexes) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/runestone/model.rb', line 38

def self.highlight_data(data, hlights, indexes)
  str = {}
  indexes.each do |key, value|
    next unless data[key]

    if data[key].is_a?(Hash)
      str[key] = highlight_data(data[key], hlights, indexes[key])
    elsif data[key].is_a?(Array)
      str[key] = data[key].map { |i|
        if i.is_a?(Hash)
          highlight_data(i, hlights, indexes[key])
        else
          hlights.shift
        end
      }
    else
      str[key] = hlights.shift
    end
  end
  str
end