Class Stat
In: app/models/stat.rb
Parent: ActiveRecord::Base

Methods

for_items   score   view   vote  

Included Modules

Constants::Stat

Public Class methods

Get stats for specific items. Any set of items should have one stat. Merge together multiple stats.

[Source]

    # File app/models/stat.rb, line 56
56:     def for_items(question_id, items)
57:       return if items.empty?
58:       joins = items.inject('') do |str, i|
59:         str += "INNER JOIN items_stats AS items_stats_#{i.id} ON (items_stats_#{i.id}.stat_id=stats.id AND
60:         items_stats_#{i.id}.item_id=#{i.id}) "
61:       end
62:       stat_ids = Stat.all(
63:         :select => "items_stats_#{items.first.id}.stat_id",
64:         :conditions => { :question_id => question_id },
65:         :joins => joins
66:       ).map(&:stat_id)
67:       if stat_ids.length > 1
68:         # merge multiple stats for same item group
69:         stats = find(stat_ids)
70:         stat = stats.shift
71:         stats.each do |el|
72:           stat.votes += el.votes
73:           stat.views += el.views
74:         end
75:         stat.score = score((stat.rank_algorithm || default_rank_algo).data.to_i, stat.votes, stat.views)
76:         stat.save!
77:         stat
78:       else
79:         !stat_ids.empty? && find(stat_ids.first)
80:       end
81:     end

Compute score as |p|^alpha, with p = 2 * votes - views, sign(n) = n / n.abs.

[Source]

    # File app/models/stat.rb, line 84
84:     def score(alpha, votes, views) #:doc:
85:       n = 2 * votes - views
86:       n != 0 ? (n / n.abs) * (n.abs) ** alpha : 0
87:     end

Update view for or create stat for items

[Source]

    # File app/models/stat.rb, line 16
16:     def view(question_id, items)
17:       return if items.empty? || !RankAlgorithm.exists?(DEFAULT_RANK_ALGO)
18:       stat = for_items(question_id, items)
19:       if stat
20:         views = stat.views + 1
21:         stat.update_attributes({ :views => views, :score => score(stat.rank_algorithm.data.to_i, stat.votes, views) })
22:       else
23:         stat = create(default(question_id))
24:         stat.items << items
25:       end
26:       stat
27:     end

Update vote for or create stat for items. Assume items are linked to the passed question id as they should be.

[Source]

    # File app/models/stat.rb, line 31
31:     def vote(question_id, items, winners = [])
32:       return if items.empty? || !RankAlgorithm.exists?(DEFAULT_RANK_ALGO)
33:       stat = for_items(question_id, items)
34:       if stat
35:         votes = stat.votes + 1
36:         # if fewer views thatn votes a view wasn't counted, set to number of votes
37:         views = stat.views < votes ? votes : stat.views
38:         options = { :votes => votes, :score => score(stat.rank_algorithm.data.to_i, votes, views) }
39:         options.merge!(:views => views) if views != stat.views
40:         stat.update_attributes(options)
41:       else
42:         stat = create(default(question_id, 1))
43:         stat.items << items
44:       end
45:       for winner in winners
46:         ItemsStat.first(:conditions => { :stat_id => stat.id, :item_id => winner.id }).increment!(:wins)
47:       end
48:       for loser in (items - winners)
49:         ItemsStat.first(:conditions => { :stat_id => stat.id, :item_id => loser.id }).increment!(:losses)
50:       end
51:       stat
52:     end

[Validate]