Commit e091d1dc8f4922a6fb6cc6b001b746e13d6e90ef
1 parent
5451b3b9
Exists in
master
and in
22 other branches
ActionItem466: changing profile categorization
automatically categorizing profiles in the whole hierarchy. For now, copy-pasted from the equivalente change in articles, but we'll (hopefully) refactor later git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@2069 3f533792-8f58-4932-b0fe-aaf55b0a4547
Showing
4 changed files
with
126 additions
and
1 deletions
Show diff stats
app/models/profile.rb
| @@ -100,7 +100,35 @@ class Profile < ActiveRecord::Base | @@ -100,7 +100,35 @@ class Profile < ActiveRecord::Base | ||
| 100 | 100 | ||
| 101 | has_many :tasks, :foreign_key => :target_id | 101 | has_many :tasks, :foreign_key => :target_id |
| 102 | 102 | ||
| 103 | - has_and_belongs_to_many :categories | 103 | + has_many :profile_categorizations, :conditions => { :virtual => false } |
| 104 | + has_many :categories, :through => :profile_categorizations | ||
| 105 | + | ||
| 106 | + def pending_categorizations | ||
| 107 | + @pending_categorizations ||= [] | ||
| 108 | + end | ||
| 109 | + | ||
| 110 | + def add_category(c) | ||
| 111 | + if self.id | ||
| 112 | + ProfileCategorization.create!(:category => c, :profile => self) | ||
| 113 | + else | ||
| 114 | + pending_categorizations << c | ||
| 115 | + end | ||
| 116 | + end | ||
| 117 | + | ||
| 118 | + def category_ids=(ids) | ||
| 119 | + ProfileCategorization.remove_all_for(self) | ||
| 120 | + ids.each do |item| | ||
| 121 | + add_category(Category.find(item)) | ||
| 122 | + end | ||
| 123 | + end | ||
| 124 | + | ||
| 125 | + after_create :create_pending_categorizations | ||
| 126 | + def create_pending_categorizations | ||
| 127 | + pending_categorizations.each do |item| | ||
| 128 | + ProfileCategorization.create!(:category => item, :profile => self) | ||
| 129 | + end | ||
| 130 | + pending_categorizations.clear | ||
| 131 | + end | ||
| 104 | 132 | ||
| 105 | def top_level_articles(reload = false) | 133 | def top_level_articles(reload = false) |
| 106 | if reload | 134 | if reload |
app/models/profile_categorization.rb
| @@ -2,4 +2,20 @@ class ProfileCategorization < ActiveRecord::Base | @@ -2,4 +2,20 @@ class ProfileCategorization < ActiveRecord::Base | ||
| 2 | set_table_name :categories_profiles | 2 | set_table_name :categories_profiles |
| 3 | belongs_to :profile | 3 | belongs_to :profile |
| 4 | belongs_to :category | 4 | belongs_to :category |
| 5 | + | ||
| 6 | + after_create :associate_with_entire_hierarchy | ||
| 7 | + def associate_with_entire_hierarchy | ||
| 8 | + return if virtual | ||
| 9 | + | ||
| 10 | + c = category.parent | ||
| 11 | + while !c.nil? && !self.class.find(:first, :conditions => {:profile_id => profile, :category_id => c}) | ||
| 12 | + self.class.create!(:profile => profile, :category => c, :virtual => true) | ||
| 13 | + c = c.parent | ||
| 14 | + end | ||
| 15 | + end | ||
| 16 | + | ||
| 17 | + def self.remove_all_for(profile) | ||
| 18 | + self.delete_all(:profile_id => profile.id) | ||
| 19 | + end | ||
| 20 | + | ||
| 5 | end | 21 | end |
test/unit/profile_categorization_test.rb
| @@ -12,4 +12,45 @@ class ProfileCategorizationTest < ActiveSupport::TestCase | @@ -12,4 +12,45 @@ class ProfileCategorizationTest < ActiveSupport::TestCase | ||
| 12 | assert_equal [cat.id], person.category_ids | 12 | assert_equal [cat.id], person.category_ids |
| 13 | end | 13 | end |
| 14 | 14 | ||
| 15 | + should 'create instances for the entire hierarchy' do | ||
| 16 | + c1 = Category.create!(:name => 'c1', :environment => Environment.default) | ||
| 17 | + c2 = c1.children.create!(:name => 'c2', :environment => Environment.default) | ||
| 18 | + | ||
| 19 | + p = create_user('testuser').person | ||
| 20 | + | ||
| 21 | + assert_difference ProfileCategorization, :count, 2 do | ||
| 22 | + ProfileCategorization.create!(:category => c2, :profile => p) | ||
| 23 | + end | ||
| 24 | + | ||
| 25 | + assert_equal 2, ProfileCategorization.find_all_by_profile_id(p.id).size | ||
| 26 | + end | ||
| 27 | + | ||
| 28 | + should 'not duplicate entry for category that is parent of two others' do | ||
| 29 | + c1 = Category.create!(:name => 'c1', :environment => Environment.default) | ||
| 30 | + c2 = c1.children.create!(:name => 'c2', :environment => Environment.default) | ||
| 31 | + c3 = c1.children.create!(:name => 'c3', :environment => Environment.default) | ||
| 32 | + | ||
| 33 | + p = create_user('testuser').person | ||
| 34 | + | ||
| 35 | + assert_difference ProfileCategorization, :count, 3 do | ||
| 36 | + ac = ProfileCategorization.create!(:category => c2, :profile => p) | ||
| 37 | + ac = ProfileCategorization.create!(:category => c3, :profile => p) | ||
| 38 | + end | ||
| 39 | + end | ||
| 40 | + | ||
| 41 | + should 'remove all instances for a given profile' do | ||
| 42 | + c1 = Category.create!(:name => 'c1', :environment => Environment.default) | ||
| 43 | + c2 = c1.children.create!(:name => 'c2', :environment => Environment.default) | ||
| 44 | + c3 = c1.children.create!(:name => 'c3', :environment => Environment.default) | ||
| 45 | + | ||
| 46 | + p = create_user('testuser').person | ||
| 47 | + | ||
| 48 | + ac = ProfileCategorization.create!(:category => c2, :profile => p) | ||
| 49 | + ac = ProfileCategorization.create!(:category => c3, :profile => p) | ||
| 50 | + | ||
| 51 | + assert_difference ProfileCategorization, :count, -3 do | ||
| 52 | + ProfileCategorization.remove_all_for(p) | ||
| 53 | + end | ||
| 54 | + end | ||
| 55 | + | ||
| 15 | end | 56 | end |
test/unit/profile_test.rb
| @@ -540,6 +540,46 @@ class ProfileTest < Test::Unit::TestCase | @@ -540,6 +540,46 @@ class ProfileTest < Test::Unit::TestCase | ||
| 540 | assert profile.enabled? | 540 | assert profile.enabled? |
| 541 | end | 541 | end |
| 542 | 542 | ||
| 543 | + should 'categorize in the entire category hierarchy' do | ||
| 544 | + c1 = Category.create!(:environment => Environment.default, :name => 'c1') | ||
| 545 | + c2 = c1.children.create!(:environment => Environment.default, :name => 'c2') | ||
| 546 | + c3 = c2.children.create!(:environment => Environment.default, :name => 'c3') | ||
| 547 | + | ||
| 548 | + profile = create_user('testuser').person | ||
| 549 | + profile.add_category(c3) | ||
| 550 | + | ||
| 551 | + | ||
| 552 | + assert_equal [c3], profile.categories(true) | ||
| 553 | + assert_equal [profile], c2.people(true) | ||
| 554 | + | ||
| 555 | + assert_includes c3.people(true), profile | ||
| 556 | + assert_includes c2.people(true), profile | ||
| 557 | + assert_includes c1.people(true), profile | ||
| 558 | + end | ||
| 559 | + | ||
| 560 | + should 'redefine the entire category set at once' do | ||
| 561 | + c1 = Category.create!(:environment => Environment.default, :name => 'c1') | ||
| 562 | + c2 = c1.children.create!(:environment => Environment.default, :name => 'c2') | ||
| 563 | + c3 = c2.children.create!(:environment => Environment.default, :name => 'c3') | ||
| 564 | + c4 = c1.children.create!(:environment => Environment.default, :name => 'c4') | ||
| 565 | + profile = Profile.create!(:name => 'my test profile', :identifier => 'mytestprofile') | ||
| 566 | + | ||
| 567 | + profile.add_category(c4) | ||
| 568 | + | ||
| 569 | + profile.category_ids = [c2,c3].map(&:id) | ||
| 570 | + | ||
| 571 | + assert_equivalent [c2, c3], profile.categories(true) | ||
| 572 | + end | ||
| 573 | + | ||
| 574 | + should 'be able to create an profile already with categories' do | ||
| 575 | + c1 = Category.create!(:environment => Environment.default, :name => 'c1') | ||
| 576 | + c2 = Category.create!(:environment => Environment.default, :name => 'c2') | ||
| 577 | + | ||
| 578 | + profile = Profile.create!(:name => 'my test profile', :identifier => 'mytestprofile', :category_ids => [c1.id, c2.id]) | ||
| 579 | + | ||
| 580 | + assert_equivalent [c1, c2], profile.categories(true) | ||
| 581 | + end | ||
| 582 | + | ||
| 543 | private | 583 | private |
| 544 | 584 | ||
| 545 | def assert_invalid_identifier(id) | 585 | def assert_invalid_identifier(id) |