about summary refs log tree commit diff
path: root/app/models/keyword_mute.rb
blob: b0229923d8744528a9c7cec947dc7768837b768b (plain) (blame)
1
2
3
4
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# frozen_string_literal: true
# == Schema Information
#
# Table name: keyword_mutes
#
#  id         :integer          not null, primary key
#  account_id :integer          not null
#  keyword    :string           not null
#  whole_word :boolean          default(TRUE), not null
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class KeywordMute < ApplicationRecord
  belongs_to :account, required: true

  validates_presence_of :keyword

  after_commit :invalidate_cached_matcher

  def self.matcher_for(account_id)
    Rails.cache.fetch("keyword_mutes:matcher:#{account_id}") { Matcher.new(account_id) }
  end

  private

  def invalidate_cached_matcher
    Rails.cache.delete("keyword_mutes:matcher:#{account_id}")
  end

  class Matcher
    attr_reader :regex

    def initialize(account_id)
      re = [].tap do |arr|
        KeywordMute.where(account_id: account_id).select(:keyword, :id, :whole_word).find_each do |m|
          boundary = m.whole_word ? '\b' : ''
          arr << "#{boundary}#{Regexp.escape(m.keyword.strip)}#{boundary}"
        end
      end.join('|')

      @regex = /#{re}/i unless re.empty?
    end

    def =~(str)
      regex ? regex =~ str : false
    end
  end
end