Commit 9afa74df42ee54e444c6f99227f069e52c1f566a

Authored by Antonio Terceiro
1 parent 4844d8a7

Smarter way of sorting profiles randomly

This fixes the problem where profiles are listed more than once in profile
listing blocks.

(ActionItem1682)
app/models/profile_list_block.rb
... ... @@ -12,12 +12,16 @@ class ProfileListBlock < Block
12 12 end
13 13  
14 14 def profile_list
15   - random = Noosfero::SQL.random_function
  15 + random = randomizer
16 16 profiles.visible.all(:limit => limit, :select => 'DISTINCT profiles.*, ' + random, :order => random)
17 17 end
18 18  
19 19 def profile_count
20   - profiles.visible.count
  20 + profiles.visible.count('DISTINCT(profiles.id)')
  21 + end
  22 +
  23 + def randomizer
  24 + @randomizer ||= "(profiles.id % #{rand(profile_count)})"
21 25 end
22 26  
23 27 # the title of the block. Probably will be overriden in subclasses.
... ...
lib/noosfero/sql.rb
... ... @@ -1,15 +0,0 @@
1   -module Noosfero
2   - module SQL
3   - class << self
4   -
5   - def random_function()
6   - default = 'random()'
7   - adapter = ActiveRecord::Base.configurations[Rails.env]['adapter']
8   - {
9   - 'mysql' => 'rand()'
10   - }[adapter] || default
11   - end
12   -
13   - end
14   - end
15   -end
test/unit/profile_list_block_test.rb
... ... @@ -141,13 +141,20 @@ class ProfileListBlockTest &lt; Test::Unit::TestCase
141 141 p2 = fast_create(Person, :environment_id => env.id)
142 142 p3 = fast_create(Person, :environment_id => env.id)
143 143  
144   - # force the "random" function to be something we know
145   - Noosfero::SQL.stubs(:random_function).returns('-id')
146   -
147 144 block = ProfileListBlock.new
148 145 block.stubs(:owner).returns(env)
149 146  
  147 + # force the "random" function to return something we know
  148 + block.stubs(:randomizer).returns('-id')
  149 +
150 150 assert_equal [p3.id, p2.id, p1.id], block.profile_list.map(&:id)
151 151 end
152 152  
  153 + should 'randomize using modulo operator and random number' do
  154 + block = ProfileListBlock.new
  155 + block.expects(:profile_count).returns(10)
  156 + block.expects(:rand).with(10).returns(5)
  157 + assert_match /profiles.id % 5/, block.randomizer
  158 + end
  159 +
153 160 end
... ...