Skip to content

Commit

Permalink
FEATURE: Basic backend support for muted and watched categories
Browse files Browse the repository at this point in the history
  • Loading branch information
SamSaffron committed Jan 2, 2014
1 parent 126433c commit b482b28
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 1 deletion.
49 changes: 49 additions & 0 deletions app/models/category_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
class CategoryUser < ActiveRecord::Base
belongs_to :category
belongs_to :user

# same for now
def self.notification_levels
TopicUser.notification_levels
end

def self.auto_watch_new_topic(topic)
apply_default_to_topic(
topic,
TopicUser.notification_levels[:watching],
TopicUser.notification_reasons[:auto_watch_category]
)
end

def self.auto_mute_new_topic(topic)
apply_default_to_topic(
topic,
TopicUser.notification_levels[:muted],
TopicUser.notification_reasons[:auto_mute_category]
)
end

private

def self.apply_default_to_topic(topic, level, reason)
# Can not afford to slow down creation of topics when a pile of users are watching new topics, reverting to SQL for max perf here
sql = <<SQL
INSERT INTO topic_users(user_id, topic_id, notification_level, notifications_reason_id)
SELECT user_id, :topic_id, :level, :reason
FROM category_users
WHERE notification_level = :level AND
category_id = :category_id AND
NOT EXISTS(SELECT 1 FROM topic_users WHERE topic_id = :topic_id AND user_id = category_users.user_id)
SQL

exec_sql(
sql,
topic_id: topic.id,
category_id: topic.category_id,
level: level,
reason: reason

)
end

end
10 changes: 9 additions & 1 deletion app/models/topic_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ def notification_levels
end

def notification_reasons
@notification_reasons ||= Enum.new(:created_topic, :user_changed, :user_interacted, :created_post, :auto_watch)
@notification_reasons ||= Enum.new(
:created_topic,
:user_changed,
:user_interacted,
:created_post,
:auto_watch,
:auto_watch_category,
:auto_mute_category
)
end

def auto_track(user_id, topic_id, reason)
Expand Down
9 changes: 9 additions & 0 deletions db/migrate/20140101235747_add_category_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class AddCategoryUsers < ActiveRecord::Migration
def change
create_table :category_users do |t|
t.column :category_id, :integer, null: false
t.column :user_id, :integer, null: false
t.column :notification_level, :integer, null: false
end
end
end
6 changes: 6 additions & 0 deletions lib/topic_creator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,23 @@ def create
save_topic

watch_topic
auto_mute_topic

@topic
end

private

def auto_mute_topic
CategoryUser.auto_mute_new_topic(@topic)
end

def watch_topic
unless @opts[:auto_track] == false
@topic.notifier.watch_topic!(@topic.user_id)
end
TopicUser.auto_watch_new_topic(@topic.id)
CategoryUser.auto_watch_new_topic(@topic)
end

def setup
Expand Down
31 changes: 31 additions & 0 deletions spec/models/category_user_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# encoding: utf-8

require 'spec_helper'
require_dependency 'post_creator'

describe CategoryUser do
context 'integration' do
before do
ActiveRecord::Base.observers.enable :all
end

it 'should operate correctly' do
watched_category = Fabricate(:category)
muted_category = Fabricate(:category)
user = Fabricate(:user)

CategoryUser.create!(user: user, category: watched_category, notification_level: CategoryUser.notification_levels[:watching])
CategoryUser.create!(user: user, category: muted_category, notification_level: CategoryUser.notification_levels[:muted])

watched_post = create_post(category: watched_category)
muted_post = create_post(category: muted_category)

Notification.where(user_id: user.id, topic_id: watched_post.topic_id).count.should == 1

tu = TopicUser.get(muted_post.topic, user)
tu.notification_level.should == TopicUser.notification_levels[:muted]
tu.notifications_reason_id.should == TopicUser.notification_reasons[:auto_mute_category]
end

end
end
2 changes: 2 additions & 0 deletions spec/support/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def create_topic(args={})
args[:title] ||= "This is my title #{Helpers.next_seq}"
user = args.delete(:user) || Fabricate(:user)
guardian = Guardian.new(user)
args[:category] = args[:category].name if Category === args[:category]
TopicCreator.create(user, guardian, args)
end

Expand All @@ -36,6 +37,7 @@ def create_post(args={})
args[:raw] ||= "This is the raw body of my post, it is cool #{Helpers.next_seq}"
args[:topic_id] = args[:topic].id if args[:topic]
user = args.delete(:user) || Fabricate(:user)
args[:category] = args[:category].name if Category === args[:category]
PostCreator.create(user, args)
end

Expand Down

0 comments on commit b482b28

Please sign in to comment.