diff --git a/app/helpers/cache_counter_helper.rb b/app/helpers/cache_counter_helper.rb new file mode 100644 index 0000000..182b791 --- /dev/null +++ b/app/helpers/cache_counter_helper.rb @@ -0,0 +1,8 @@ +module CacheCounterHelper + def update_cache_counter(name, object, value) + if object.present? + object.send(name.to_s+'=', object.send(name) + value) + object.save! + end + end +end diff --git a/app/models/friendship.rb b/app/models/friendship.rb index 8df2844..ff669c8 100644 --- a/app/models/friendship.rb +++ b/app/models/friendship.rb @@ -1,6 +1,18 @@ class Friendship < ActiveRecord::Base track_actions :new_friendship, :after_create, :keep_params => ["friend.name", "friend.url", "friend.profile_custom_icon"], :custom_user => :person - + + extend CacheCounterHelper + belongs_to :person, :foreign_key => :person_id belongs_to :friend, :class_name => 'Person', :foreign_key => 'friend_id' + + after_create do |friendship| + update_cache_counter(:friends_count, friendship.person, 1) + update_cache_counter(:friends_count, friendship.friend, 1) + end + + after_destroy do |friendship| + update_cache_counter(:friends_count, friendship.person, -1) + update_cache_counter(:friends_count, friendship.friend, -1) + end end diff --git a/app/models/person.rb b/app/models/person.rb index d6cb455..202a23b 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -66,11 +66,7 @@ class Person < Profile has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' - named_scope :more_popular, - :select => "#{Profile.qualified_column_names}, count(friend_id) as total", - :group => Profile.qualified_column_names, - :joins => "LEFT OUTER JOIN friendships on profiles.id = friendships.person_id", - :order => "total DESC" + named_scope :more_popular, :order => 'friends_count DESC' named_scope :more_active, :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total", diff --git a/db/migrate/20140312144156_define_initial_value_for_profiles_friends_count.rb b/db/migrate/20140312144156_define_initial_value_for_profiles_friends_count.rb new file mode 100644 index 0000000..28353b3 --- /dev/null +++ b/db/migrate/20140312144156_define_initial_value_for_profiles_friends_count.rb @@ -0,0 +1,12 @@ +class DefineInitialValueForProfilesFriendsCount < ActiveRecord::Migration + def self.up + friends_counts = execute("SELECT profiles.id, count(profiles.id) FROM profiles INNER JOIN friendships ON ( profiles.id = friendships.friend_id AND profiles.type = E'Person') GROUP BY profiles.id;") + friends_counts.each do |count| + execute("UPDATE profiles SET friends_count=#{count['count'].to_i} WHERE profiles.id=#{count['id']};") + end + end + + def self.down + execute("UPDATE profiles SET friends_count=0;") + end +end diff --git a/test/unit/person_test.rb b/test/unit/person_test.rb index 49f2826..4f48fb4 100644 --- a/test/unit/person_test.rb +++ b/test/unit/person_test.rb @@ -647,11 +647,14 @@ class PersonTest < ActiveSupport::TestCase p2 = fast_create(Person) p3 = fast_create(Person) - p1.add_friend(p2) - p2.add_friend(p1) - p2.add_friend(p3) - assert_equal p2, Person.more_popular[0] - assert_equal p1, Person.more_popular[1] + p1.friends_count = 1 + p2.friends_count = 2 + p3.friends_count = 3 + p1.save! + p2.save! + p3.save! + + assert_order [p3, p2, p1], Person.more_popular end should 'list people that have no friends in more popular list' do @@ -1363,7 +1366,7 @@ class PersonTest < ActiveSupport::TestCase u = create_user('user'+i.to_s) u.deactivate } - assert_equal activated, Person.activated + assert_equivalent activated, Person.activated end should 'deactivated named_scope return persons who are deactivated users' do @@ -1413,4 +1416,31 @@ class PersonTest < ActiveSupport::TestCase person.reload assert_equal person.activities, [] end + + should 'increase friends_count on new friendship' do + person = create_user('person').person + friend = create_user('friend').person + assert_difference person, :friends_count, 1 do + assert_difference friend, :friends_count, 1 do + person.add_friend(friend) + friend.reload + end + person.reload + end + end + + should 'decrease friends_count on new friendship' do + person = create_user('person').person + friend = create_user('friend').person + person.add_friend(friend) + friend.reload + person.reload + assert_difference person, :friends_count, -1 do + assert_difference friend, :friends_count, -1 do + person.remove_friend(friend) + friend.reload + end + person.reload + end + end end -- libgit2 0.21.2