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 | 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) | ... | ... |