Commit e091d1dc8f4922a6fb6cc6b001b746e13d6e90ef
1 parent
5451b3b9
Exists in
master
and in
23 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 | 100 | |
| 101 | 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 | 133 | def top_level_articles(reload = false) |
| 106 | 134 | if reload | ... | ... |
app/models/profile_categorization.rb
| ... | ... | @@ -2,4 +2,20 @@ class ProfileCategorization < ActiveRecord::Base |
| 2 | 2 | set_table_name :categories_profiles |
| 3 | 3 | belongs_to :profile |
| 4 | 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 | 21 | end | ... | ... |
test/unit/profile_categorization_test.rb
| ... | ... | @@ -12,4 +12,45 @@ class ProfileCategorizationTest < ActiveSupport::TestCase |
| 12 | 12 | assert_equal [cat.id], person.category_ids |
| 13 | 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 | 56 | end | ... | ... |
test/unit/profile_test.rb
| ... | ... | @@ -540,6 +540,46 @@ class ProfileTest < Test::Unit::TestCase |
| 540 | 540 | assert profile.enabled? |
| 541 | 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 | 583 | private |
| 544 | 584 | |
| 545 | 585 | def assert_invalid_identifier(id) | ... | ... |