Commit c124eb8e7709f777e7f6e48cba3f74c8e9fdb055
1 parent
82dae706
Exists in
master
and in
29 other branches
organization: register and use members_count to fetch most_popular organizations
(ActionItem3039)
Showing
7 changed files
with
95 additions
and
12 deletions
Show diff stats
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
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 < 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 < 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 < 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 < 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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |