Commit c124eb8e7709f777e7f6e48cba3f74c8e9fdb055

Authored by Rodrigo Souto
1 parent 82dae706

organization: register and use members_count to fetch most_popular organizations

(ActionItem3039)
app/models/organization.rb
@@ -26,11 +26,7 @@ class Organization < Profile @@ -26,11 +26,7 @@ class Organization < Profile
26 26
27 has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' 27 has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source'
28 28
29 - named_scope :more_popular,  
30 - :select => "#{Profile.qualified_column_names}, count(resource_id) as total",  
31 - :group => Profile.qualified_column_names,  
32 - :joins => "LEFT OUTER JOIN role_assignments ON profiles.id = role_assignments.resource_id",  
33 - :order => "total DESC" 29 + named_scope :more_popular, :order => 'members_count DESC'
34 30
35 def validation_methodology 31 def validation_methodology
36 self.validation_info ? self.validation_info.validation_methodology : nil 32 self.validation_info ? self.validation_info.validation_methodology : nil
app/models/profile.rb
@@ -87,10 +87,6 @@ class Profile < ActiveRecord::Base @@ -87,10 +87,6 @@ class Profile < ActiveRecord::Base
87 scopes.size == 1 ? scopes.first : Person.or_scope(scopes) 87 scopes.size == 1 ? scopes.first : Person.or_scope(scopes)
88 end 88 end
89 89
90 - def members_count  
91 - members.count  
92 - end  
93 -  
94 class << self 90 class << self
95 def count_with_distinct(*args) 91 def count_with_distinct(*args)
96 options = args.last || {} 92 options = args.last || {}
config/initializers/noosfero_extensions.rb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +require 'noosfero/role_assignment_ext'
db/migrate/20140313213142_define_initial_value_for_profiles_members_count.rb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +class DefineInitialValueForProfilesMembersCount < ActiveRecord::Migration
  2 + def self.up
  3 + members_counts = execute("SELECT profiles.id, count(profiles.id) FROM profiles LEFT OUTER JOIN role_assignments ON profiles.id = role_assignments.resource_id WHERE (profiles.type = 'Organization' OR profiles.type = 'Community' OR profiles.type = 'Enterprise') GROUP BY profiles.id;")
  4 + members_counts.each do |count|
  5 + execute("UPDATE profiles SET members_count=#{count['count'].to_i} WHERE profiles.id=#{count['id']};")
  6 + end
  7 + end
  8 +
  9 + def self.down
  10 + execute("UPDATE profiles SET members_count=0;")
  11 + end
  12 +end
lib/noosfero/role_assignment_ext.rb 0 → 100644
@@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
  1 +Rails.configuration.to_prepare do
  2 + RoleAssignment.module_eval do
  3 + extend CacheCounterHelper
  4 +
  5 + after_create do |role_assignment|
  6 + accessor = role_assignment.accessor
  7 + resource = role_assignment.resource
  8 + if resource.kind_of?(Organization)
  9 + #FIXME This will only work as long as the role_assignment associations
  10 + #happen only between profiles, due to the polymorphic column type.
  11 + if resource.role_assignments.where(:accessor_id => accessor.id).count == 1
  12 + update_cache_counter(:members_count, resource, 1)
  13 + end
  14 + end
  15 + end
  16 +
  17 + after_destroy do |role_assignment|
  18 + accessor = role_assignment.accessor
  19 + resource = role_assignment.resource
  20 + if resource.kind_of?(Organization)
  21 + #FIXME This will only work as long as the role_assignment associations
  22 + #happen only between profiles, due to the polymorphic column type.
  23 + if resource.role_assignments.where(:accessor_id => accessor.id).count == 0
  24 + update_cache_counter(:members_count, resource, -1)
  25 + end
  26 + end
  27 + end
  28 + end
  29 +end
test/unit/organization_test.rb
@@ -302,18 +302,17 @@ class OrganizationTest &lt; ActiveSupport::TestCase @@ -302,18 +302,17 @@ class OrganizationTest &lt; ActiveSupport::TestCase
302 end 302 end
303 303
304 should 'find more popular organizations' do 304 should 'find more popular organizations' do
305 - Organization.delete_all  
306 o1 = fast_create(Organization) 305 o1 = fast_create(Organization)
307 o2 = fast_create(Organization) 306 o2 = fast_create(Organization)
308 307
309 p1 = fast_create(Person) 308 p1 = fast_create(Person)
310 p2 = fast_create(Person) 309 p2 = fast_create(Person)
311 o1.add_member(p1) 310 o1.add_member(p1)
312 - assert_equal [o1,o2] , Organization.more_popular 311 + assert_order [o1,o2] , Organization.more_popular
313 312
314 o2.add_member(p1) 313 o2.add_member(p1)
315 o2.add_member(p2) 314 o2.add_member(p2)
316 - assert_equal [o2,o1] , Organization.more_popular 315 + assert_order [o2,o1] , Organization.more_popular
317 end 316 end
318 317
319 should 'list organizations that have no members in more popular list' do 318 should 'list organizations that have no members in more popular list' do
@@ -331,6 +330,7 @@ class OrganizationTest &lt; ActiveSupport::TestCase @@ -331,6 +330,7 @@ class OrganizationTest &lt; ActiveSupport::TestCase
331 person = fast_create(Person) 330 person = fast_create(Person)
332 organization = fast_create(Organization) 331 organization = fast_create(Organization)
333 organization.add_member(person) 332 organization.add_member(person)
  333 + organization.reload
334 334
335 assert_equal "one member", organization.more_popular_label 335 assert_equal "one member", organization.more_popular_label
336 end 336 end
@@ -342,10 +342,12 @@ class OrganizationTest &lt; ActiveSupport::TestCase @@ -342,10 +342,12 @@ class OrganizationTest &lt; ActiveSupport::TestCase
342 342
343 organization.add_member(person1) 343 organization.add_member(person1)
344 organization.add_member(person2) 344 organization.add_member(person2)
  345 + organization.reload
345 assert_equal "2 members", organization.more_popular_label 346 assert_equal "2 members", organization.more_popular_label
346 347
347 person3 = fast_create(Person) 348 person3 = fast_create(Person)
348 organization.add_member(person3) 349 organization.add_member(person3)
  350 + organization.reload
349 assert_equal "3 members", organization.more_popular_label 351 assert_equal "3 members", organization.more_popular_label
350 end 352 end
351 353
@@ -433,5 +435,24 @@ class OrganizationTest &lt; ActiveSupport::TestCase @@ -433,5 +435,24 @@ class OrganizationTest &lt; ActiveSupport::TestCase
433 end 435 end
434 end 436 end
435 437
  438 + should 'increase members_count on new membership' do
  439 + member = fast_create(Person)
  440 + organization = fast_create(Organization)
  441 + assert_difference organization, :members_count, 1 do
  442 + organization.add_member(member)
  443 + organization.reload
  444 + end
  445 + end
  446 +
  447 + should 'decrease members_count on membership removal' do
  448 + member = fast_create(Person)
  449 + organization = fast_create(Organization)
  450 + organization.add_member(member)
  451 + organization.reload
  452 + assert_difference organization, :members_count, -1 do
  453 + organization.remove_member(member)
  454 + organization.reload
  455 + end
  456 + end
436 457
437 end 458 end
test/unit/role_assignment_ext_test.rb 0 → 100644
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class RoleAssignmentExtTest < ActiveSupport::TestCase
  4 + should 'increase organization members_count only on the first role_assignment' do
  5 + role1 = Role.create!(:name => 'role1')
  6 + role2 = Role.create!(:name => 'role2')
  7 + member = create_user('person').person
  8 + organization = Organization.create!(:name => 'Organization', :identifier => 'organization')
  9 + assert_difference organization, :members_count, 1 do
  10 + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role1)
  11 + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role2)
  12 + organization.reload
  13 + end
  14 + end
  15 +
  16 + should 'decrease organization members_count only on the last role_assignment' do
  17 + role1 = Role.create!(:name => 'role1')
  18 + role2 = Role.create!(:name => 'role2')
  19 + member = create_user('person').person
  20 + organization = Organization.create!(:name => 'Organization', :identifier => 'organization')
  21 + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role1)
  22 + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role2)
  23 + assert_difference organization, :members_count, -1 do
  24 + organization.role_assignments.destroy_all
  25 + organization.reload
  26 + end
  27 + end
  28 +end