discourse-chat-integration/app/models/rule.rb

129 lines
3.4 KiB
Ruby
Raw Normal View History

class DiscourseChat::Rule < DiscourseChat::PluginModel
# Setup ActiveRecord::Store to use the JSON field to read/write these values
store :value, accessors: [ :channel_id, :type, :group_id, :category_id, :tags, :filter ], coder: JSON
2017-09-28 04:32:38 -04:00
scope :with_type, ->(type) { where("value::json->>'type'=?", type.to_s) }
scope :with_channel, ->(channel) { with_channel_id(channel.id) }
scope :with_channel_id, ->(channel_id) { where("value::json->>'channel_id'=?", channel_id.to_s) }
2017-10-03 03:30:38 -04:00
scope :with_category_id, ->(category_id) do
if category_id.nil?
where("(value::json->'category_id') IS NULL OR json_typeof(value::json->'category_id')='null'")
else
where("value::json->>'category_id'=?", category_id.to_s)
end
end
scope :with_group_ids, ->(group_id) do
where("value::json->>'group_id' IN (?)", group_id.map!(&:to_s))
end
scope :order_by_precedence, -> {
order("
CASE
WHEN value::json->>'type' = 'group_mention' THEN 1
WHEN value::json->>'type' = 'group_message' THEN 2
ELSE 3
END
",
"
CASE
WHEN value::json->>'filter' = 'mute' THEN 1
WHEN value::json->>'filter' = 'watch' THEN 2
WHEN value::json->>'filter' = 'follow' THEN 3
END
")
}
2017-09-28 04:32:38 -04:00
after_initialize :init_filter
2017-08-01 15:53:39 -04:00
validates :filter, inclusion: { in: %w(watch follow mute),
message: "%{value} is not a valid filter" }
2017-08-01 15:53:39 -04:00
validates :type, inclusion: { in: %w(normal group_message group_mention),
message: "%{value} is not a valid filter" }
validate :channel_valid?, :category_valid?, :group_valid?, :tags_valid?
def self.key_prefix
'rule:'.freeze
end
# We never want an empty array, set it to nil instead
def tags=(array)
2017-08-01 15:53:39 -04:00
if array.nil? || array.empty?
super(nil)
else
super(array)
end
end
2017-07-31 12:09:21 -04:00
# These are only allowed to be integers
%w(channel_id category_id group_id).each do |name|
define_method "#{name}=" do |val|
2017-08-01 15:53:39 -04:00
if val.nil? || val.blank?
2017-07-31 12:09:21 -04:00
super(nil)
else
super(val.to_i)
end
end
end
2017-07-13 11:09:34 -04:00
# Mock foreign key
# Could return nil
2017-07-13 11:09:34 -04:00
def channel
2017-08-01 15:53:39 -04:00
DiscourseChat::Channel.find_by(id: channel_id)
2017-07-13 11:09:34 -04:00
end
2017-10-03 03:30:38 -04:00
2017-07-13 11:09:34 -04:00
def channel=(val)
self.channel_id = val.id
end
2017-09-28 04:32:38 -04:00
private
2017-09-28 04:32:38 -04:00
def channel_valid?
if !(DiscourseChat::Channel.where(id: channel_id).exists?)
errors.add(:channel_id, "#{channel_id} is not a valid channel id")
end
end
2017-07-03 12:38:13 -04:00
2017-09-28 04:32:38 -04:00
def category_valid?
if type != 'normal' && !category_id.nil?
errors.add(:category_id, "cannot be specified for that type of rule")
end
2017-09-28 04:32:38 -04:00
return unless type == 'normal'
if !(category_id.nil? || Category.where(id: category_id).exists?)
errors.add(:category_id, "#{category_id} is not a valid category id")
end
end
def group_valid?
if type == 'normal' && !group_id.nil?
errors.add(:group_id, "cannot be specified for that type of rule")
end
2017-09-28 04:32:38 -04:00
return if type == 'normal'
if !Group.where(id: group_id).exists?
errors.add(:group_id, "#{group_id} is not a valid group id")
end
end
def tags_valid?
return if tags.nil?
2017-10-03 03:30:38 -04:00
2017-09-28 04:32:38 -04:00
tags.each do |tag|
if !Tag.where(name: tag).exists?
errors.add(:tags, "#{tag} is not a valid tag")
end
end
end
def init_filter
self.filter ||= 'watch'
self.type ||= 'normal'
end
2017-08-01 15:53:39 -04:00
end