custom_filter.rb 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. # frozen_string_literal: true
  2. # == Schema Information
  3. #
  4. # Table name: custom_filters
  5. #
  6. # id :bigint(8) not null, primary key
  7. # account_id :bigint(8)
  8. # expires_at :datetime
  9. # phrase :text default(""), not null
  10. # context :string default([]), not null, is an Array
  11. # whole_word :boolean default(TRUE), not null
  12. # irreversible :boolean default(FALSE), not null
  13. # created_at :datetime not null
  14. # updated_at :datetime not null
  15. #
  16. class CustomFilter < ApplicationRecord
  17. VALID_CONTEXTS = %w(
  18. home
  19. notifications
  20. public
  21. thread
  22. account
  23. ).freeze
  24. include Expireable
  25. include Redisable
  26. belongs_to :account
  27. validates :phrase, :context, presence: true
  28. validate :context_must_be_valid
  29. validate :irreversible_must_be_within_context
  30. scope :active_irreversible, -> { where(irreversible: true).where(Arel.sql('expires_at IS NULL OR expires_at > NOW()')) }
  31. before_validation :clean_up_contexts
  32. after_commit :remove_cache
  33. def expires_in
  34. return @expires_in if defined?(@expires_in)
  35. return nil if expires_at.nil?
  36. [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].find { |expires_in| expires_in.from_now >= expires_at }
  37. end
  38. private
  39. def clean_up_contexts
  40. self.context = Array(context).map(&:strip).filter_map(&:presence)
  41. end
  42. def remove_cache
  43. Rails.cache.delete("filters:#{account_id}")
  44. redis.publish("timeline:#{account_id}", Oj.dump(event: :filters_changed))
  45. end
  46. def context_must_be_valid
  47. errors.add(:context, I18n.t('filters.errors.invalid_context')) if context.empty? || context.any? { |c| !VALID_CONTEXTS.include?(c) }
  48. end
  49. def irreversible_must_be_within_context
  50. errors.add(:irreversible, I18n.t('filters.errors.invalid_irreversible')) if irreversible? && !context.include?('home') && !context.include?('notifications')
  51. end
  52. end