2016-07-06 15:56:40 -04:00
require_dependency 'notification_levels'
2014-01-02 12:00:08 +11:00
class CategoryUser < ActiveRecord :: Base
belongs_to :category
belongs_to :user
2014-01-02 17:58:49 +11:00
def self . lookup ( user , level )
self . where ( user : user , notification_level : notification_levels [ level ] )
end
2014-04-17 11:17:39 +02:00
def self . lookup_by_category ( user , category )
self . where ( user : user , category : category )
end
2014-01-02 12:00:08 +11:00
def self . notification_levels
2016-07-06 15:56:40 -04:00
NotificationLevels . all
2016-07-05 15:16:32 -04:00
end
def self . watching_levels
[ notification_levels [ :watching ] , notification_levels [ :watching_first_post ] ]
2014-01-02 12:00:08 +11:00
end
2014-01-02 17:58:49 +11:00
def self . batch_set ( user , level , category_ids )
records = CategoryUser . where ( user : user , notification_level : notification_levels [ level ] )
old_ids = records . pluck ( :category_id )
2016-07-08 12:58:18 +10:00
changed = false
2014-01-02 17:58:49 +11:00
2014-01-08 17:10:16 +11:00
category_ids = Category . where ( 'id in (?)' , category_ids ) . pluck ( :id )
2014-01-02 17:58:49 +11:00
remove = ( old_ids - category_ids )
if remove . present?
records . where ( 'category_id in (?)' , remove ) . destroy_all
2016-07-08 12:58:18 +10:00
changed = true
2014-01-02 17:58:49 +11:00
end
( category_ids - old_ids ) . each do | id |
CategoryUser . create! ( user : user , category_id : id , notification_level : notification_levels [ level ] )
2016-07-08 12:58:18 +10:00
changed = true
end
if changed
auto_watch ( user_id : user . id )
auto_track ( user_id : user . id )
2014-01-02 17:58:49 +11:00
end
2016-07-08 12:58:18 +10:00
changed
2014-01-02 17:58:49 +11:00
end
2014-04-17 11:17:39 +02:00
def self . set_notification_level_for_category ( user , level , category_id )
record = CategoryUser . where ( user : user , category_id : category_id ) . first
2016-07-08 12:58:18 +10:00
return if record && record . notification_level = level
2014-04-17 11:17:39 +02:00
if record . present?
record . notification_level = level
record . save!
else
CategoryUser . create! ( user : user , category_id : category_id , notification_level : level )
end
2016-07-08 12:58:18 +10:00
auto_watch ( user_id : user . id )
auto_track ( user_id : user . id )
2014-04-17 11:17:39 +02:00
end
2016-07-08 12:58:18 +10:00
def self . auto_track ( opts = { } )
builder = SqlBuilder . new <<SQL
UPDATE topic_users tu
SET notification_level = :tracking ,
notifications_reason_id = :auto_track_category
FROM topics t , category_users cu
/ *where* /
SQL
builder . where ( " tu.topic_id = t.id AND
cu . category_id = t . category_id AND
cu . user_id = tu . user_id AND
cu . notification_level = :tracking AND
tu . notification_level = :regular " )
if category_id = opts [ :category_id ]
builder . where ( " t.category_id = :category_id " , category_id : category_id )
end
if topic_id = opts [ :topic_id ]
builder . where ( " tu.topic_id = :topic_id " , topic_id : topic_id )
end
if user_id = opts [ :user_id ]
builder . where ( " tu.user_id = :user_id " , user_id : user_id )
end
builder . exec ( tracking : notification_levels [ :tracking ] ,
regular : notification_levels [ :regular ] ,
auto_track_category : TopicUser . notification_reasons [ :auto_track_category ] )
2015-08-19 22:40:20 +02:00
end
2016-07-08 12:58:18 +10:00
def self . auto_watch ( opts = { } )
builder = SqlBuilder . new <<SQL
UPDATE topic_users tu
SET notification_level =
CASE WHEN should_track THEN :tracking
WHEN should_watch THEN :watching
ELSE notification_level
END ,
notifications_reason_id =
CASE WHEN should_track THEN null
WHEN should_watch THEN :auto_watch_category
ELSE notifications_reason_id
END
FROM (
SELECT tu1 . topic_id ,
tu1 . user_id ,
CASE WHEN
cu . user_id IS NULL AND tu1 . notification_level = :watching AND tu1 . notifications_reason_id = :auto_watch_category THEN true
ELSE false
END should_track ,
CASE WHEN
cu . user_id IS NOT NULL AND tu1 . notification_level in ( :regular , :tracking ) THEN true
ELSE false
END should_watch
FROM topic_users tu1
JOIN topics t ON t . id = tu1 . topic_id
LEFT JOIN category_users cu ON cu . category_id = t . category_id AND cu . user_id = tu1 . user_id AND cu . notification_level = :watching
/ *where2* /
) as X
/ *where* /
SQL
builder . where ( " X.topic_id = tu.topic_id AND X.user_id = tu.user_id " )
builder . where ( " should_watch OR should_track " )
if category_id = opts [ :category_id ]
builder . where2 ( " t.category_id = :category_id " , category_id : category_id )
end
if topic_id = opts [ :topic_id ]
builder . where ( " tu.topic_id = :topic_id " , topic_id : topic_id )
builder . where2 ( " tu1.topic_id = :topic_id " , topic_id : topic_id )
end
if user_id = opts [ :user_id ]
builder . where ( " tu.user_id = :user_id " , user_id : user_id )
builder . where2 ( " tu1.user_id = :user_id " , user_id : user_id )
end
builder . exec ( watching : notification_levels [ :watching ] ,
tracking : notification_levels [ :tracking ] ,
regular : notification_levels [ :regular ] ,
auto_watch_category : TopicUser . notification_reasons [ :auto_watch_category ] )
2014-01-02 12:00:08 +11:00
end
2016-07-08 12:58:18 +10:00
2015-09-02 22:02:31 +02:00
def self . ensure_consistency!
2016-02-15 18:54:53 +11:00
exec_sql <<SQL
DELETE FROM category_users
WHERE user_id IN (
SELECT cu . user_id FROM category_users cu
LEFT JOIN users u ON u . id = cu . user_id
WHERE u . id IS NULL
)
SQL
2015-09-02 22:02:31 +02:00
end
2014-01-02 12:00:08 +11:00
end
2014-02-07 11:07:36 +11:00
# == Schema Information
#
# Table name: category_users
#
# id :integer not null, primary key
# category_id :integer not null
# user_id :integer not null
# notification_level :integer not null
#
2016-01-11 17:30:56 +11:00
# Indexes
#
# idx_category_users_u1 (user_id,category_id,notification_level) UNIQUE
# idx_category_users_u2 (category_id,user_id,notification_level) UNIQUE
#