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 26  
27 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 31 def validation_methodology
36 32 self.validation_info ? self.validation_info.validation_methodology : nil
... ...
app/models/profile.rb
... ... @@ -87,10 +87,6 @@ class Profile < ActiveRecord::Base
87 87 scopes.size == 1 ? scopes.first : Person.or_scope(scopes)
88 88 end
89 89  
90   - def members_count
91   - members.count
92   - end
93   -
94 90 class << self
95 91 def count_with_distinct(*args)
96 92 options = args.last || {}
... ...
config/initializers/noosfero_extensions.rb 0 → 100644
... ... @@ -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 @@
  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 @@
  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 302 end
303 303  
304 304 should 'find more popular organizations' do
305   - Organization.delete_all
306 305 o1 = fast_create(Organization)
307 306 o2 = fast_create(Organization)
308 307  
309 308 p1 = fast_create(Person)
310 309 p2 = fast_create(Person)
311 310 o1.add_member(p1)
312   - assert_equal [o1,o2] , Organization.more_popular
  311 + assert_order [o1,o2] , Organization.more_popular
313 312  
314 313 o2.add_member(p1)
315 314 o2.add_member(p2)
316   - assert_equal [o2,o1] , Organization.more_popular
  315 + assert_order [o2,o1] , Organization.more_popular
317 316 end
318 317  
319 318 should 'list organizations that have no members in more popular list' do
... ... @@ -331,6 +330,7 @@ class OrganizationTest &lt; ActiveSupport::TestCase
331 330 person = fast_create(Person)
332 331 organization = fast_create(Organization)
333 332 organization.add_member(person)
  333 + organization.reload
334 334  
335 335 assert_equal "one member", organization.more_popular_label
336 336 end
... ... @@ -342,10 +342,12 @@ class OrganizationTest &lt; ActiveSupport::TestCase
342 342  
343 343 organization.add_member(person1)
344 344 organization.add_member(person2)
  345 + organization.reload
345 346 assert_equal "2 members", organization.more_popular_label
346 347  
347 348 person3 = fast_create(Person)
348 349 organization.add_member(person3)
  350 + organization.reload
349 351 assert_equal "3 members", organization.more_popular_label
350 352 end
351 353  
... ... @@ -433,5 +435,24 @@ class OrganizationTest &lt; ActiveSupport::TestCase
433 435 end
434 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 458 end
... ...
test/unit/role_assignment_ext_test.rb 0 → 100644
... ... @@ -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
... ...