Commit e091d1dc8f4922a6fb6cc6b001b746e13d6e90ef
1 parent
5451b3b9
Exists in
master
and in
29 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) |