Commit e091d1dc8f4922a6fb6cc6b001b746e13d6e90ef

Authored by AntonioTerceiro
1 parent 5451b3b9

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
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 &lt; 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 &lt; 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 &lt; 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)
... ...