some auto follow/unfollow fixes for sharding

also a fix for UserFollow#check_auto_follow_collections, which was kind
of only working by accident across shards.

test plan: have a user join a group in another shard, and see that they
auto-follow collections in the group. have them leave the group, and see
that they auto-unfollow private collections in the group.

Change-Id: Ic1efd9e527d14d4a21c0db828ba228dd0b3753e8
Reviewed-on: https://gerrit.instructure.com/11719
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Simon Williams <simon@instructure.com>
This commit is contained in:
Brian Palmer 2012-06-20 15:05:53 -06:00
parent 91a4856514
commit 0be73307fc
4 changed files with 40 additions and 11 deletions

View File

@ -134,15 +134,18 @@ class Group < ActiveRecord::Base
end
def membership_for_user(user)
self.group_memberships.find_by_user_id(user && user.id)
return nil unless user.present?
self.shard.activate { self.group_memberships.find_by_user_id(user.id) }
end
def has_member?(user)
self.participating_group_memberships.find_by_user_id(user && user.id)
return nil unless user.present?
self.shard.activate { self.participating_group_memberships.find_by_user_id(user.id) }
end
def has_moderator?(user)
self.participating_group_memberships.moderators.find_by_user_id(user && user.id)
return nil unless user.present?
self.shard.activate { self.participating_group_memberships.moderators.find_by_user_id(user.id) }
end
def should_add_creator?

View File

@ -112,7 +112,7 @@ class GroupMembership < ActiveRecord::Base
if (self.id_changed? || self.workflow_state_changed?) && self.active?
UserFollow.create_follow(self.user, self.group)
elsif self.destroyed? || (self.workflow_state_changed? && self.deleted?)
user_follow = self.user.user_follows.find(:first, :conditions => { :followed_item_id => self.group_id, :followed_item_type => 'Group' })
user_follow = self.user.shard.activate { self.user.user_follows.find(:first, :conditions => { :followed_item_id => self.group_id, :followed_item_type => 'Group' }) }
user_follow.try(:destroy)
end
end

View File

@ -68,14 +68,25 @@ class UserFollow < ActiveRecord::Base
#
# this way both associations work as expected
set_shard_override do |record|
record.following_user.shard unless record.complementary_record
record.following_user.shard unless record.complementary_record?
end
after_create :create_complementary_record
attr_accessor :complementary_record
attr_writer :complementary_record
# returns true if the following user isn't on the same shard as the followed
# item, and this UserFollow is the secondary copy that's on the followed
# item's shard
def complementary_record?
if new_record?
@complementary_record
else
self.shard != following_user.shard
end
end
def create_complementary_record
if !complementary_record && followed_item.shard != following_user.shard
if !complementary_record? && followed_item.shard != following_user.shard
followed_item.shard.activate do
UserFollow.create_follow(following_user, followed_item, true)
end
@ -85,10 +96,10 @@ class UserFollow < ActiveRecord::Base
after_destroy :destroy_complementary_record
def destroy_complementary_record
complementary_record.try(:destroy)
find_complementary_record.try(:destroy)
end
def complementary_record
def find_complementary_record
return nil if followed_item.shard == following_user.shard
if self.shard == followed_item.shard
finding_shard = following_user.shard
@ -110,7 +121,7 @@ class UserFollow < ActiveRecord::Base
# when a user follows a group or other user, they auto-follow all existing
# collections in that context as well
def check_auto_follow_collections
return true if complementary_record
return true if self.complementary_record?
case followed_item
when User, Group
if !followed_item.collections.empty?
@ -133,7 +144,7 @@ class UserFollow < ActiveRecord::Base
# when a user leaves a group, they auto-unfollow all private collections in
# that group
def check_auto_unfollow_collections
return true if complementary_record
return true if self.complementary_record?
case followed_item
when Group
if !followed_item.collections.empty?

View File

@ -68,6 +68,21 @@ describe "UserFollow" do
expect { @uf.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
it "should unfollow private collections on group unfollow" do
@shard1.activate do
@group = Group.create!(:group_category => GroupCategory.communities_for(Account.default), :is_public => true, :join_level => 'parent_context_auto_join')
@coll = @group.collections.create!(:name => 'col1', :visibility => 'private')
end
@membership = @group.add_user(@user1)
@follow = @group.following_user_follows.first
@follow.following_user.should == @user1
run_jobs
@coll.reload.following_user_follows.map(&:following_user).should == [@user1]
@membership.destroy
run_jobs
@coll.reload.following_user_follows.map(&:following_user).should == []
end
def verify
yield
@shard1.activate { yield }