Module: Letsrate

Extended by:
ActiveSupport::Concern
Included in:
ActiveRecord::Base
Defined in:
lib/letsrate.rb,
lib/letsrate/model.rb,
lib/letsrate/version.rb

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

VERSION =
"1.0.9"

Instance Method Summary collapse

Instance Method Details

#average(dimension = nil) ⇒ Object



64
65
66
# File 'lib/letsrate/model.rb', line 64

def average(dimension=nil)
  dimension ?  self.send("#{dimension}_average") : rate_average_without_dimension
end

#can_rate?(user, dimension = nil) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/letsrate/model.rb', line 68

def can_rate?(user, dimension=nil)
  user.ratings_given.where(dimension: dimension, rateable_id: id, rateable_type: self.class.name).size.zero?
end

#rate(stars, user, dimension = nil, dirichlet_method = false) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/letsrate/model.rb', line 5

def rate(stars, user, dimension=nil, dirichlet_method=false)
  dimension = nil if dimension.blank?

  if can_rate? user, dimension
    rates(dimension).create! do |r|
      r.stars = stars
      r.rater = user
    end
    if dirichlet_method
      update_rate_average_dirichlet(stars, dimension)
    else
      update_rate_average(stars, dimension)
    end
  else
    raise "User has already rated."
  end
end

#raters(dimension = nil) ⇒ Object



76
77
78
# File 'lib/letsrate/model.rb', line 76

def raters(dimension=nil)
  dimension ? self.send("#{dimension}_raters") : raters_without_dimension
end

#rates(dimension = nil) ⇒ Object



72
73
74
# File 'lib/letsrate/model.rb', line 72

def rates(dimension=nil)
  dimension ? self.send("#{dimension}_rates") : rates_without_dimension
end

#update_rate_average(stars, dimension = nil) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/letsrate/model.rb', line 47

def update_rate_average(stars, dimension=nil)
  if average(dimension).nil?
    RatingCache.create! do |avg|
      avg.cacheable_id = self.id
      avg.cacheable_type = self.class.name
      avg.avg = stars
      avg.qty = 1
      avg.dimension = dimension
    end
  else
    a = average(dimension)
    a.qty = rates(dimension).count
    a.avg = rates(dimension).average(:stars)
    a.save!(validate: false)
  end
end

#update_rate_average_dirichlet(stars, dimension = nil) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/letsrate/model.rb', line 23

def update_rate_average_dirichlet(stars, dimension=nil)
  ## assumes 5 possible vote categories
  dp = {1 => 1, 2 => 1, 3 => 1, 4 => 1, 5 => 1}
  stars_group = Hash[rates(dimension).group(:stars).count.map{|k,v| [k.to_i,v] }]
  posterior = dp.merge(stars_group){|key, a, b| a + b}
  sum = posterior.map{ |i, v| v }.inject { |a, b| a + b }
  davg = posterior.map{ |i, v| i * v }.inject { |a, b| a + b }.to_f / sum

  if average(dimension).nil?
    RatingCache.create! do |avg|
      avg.cacheable_id = self.id
      avg.cacheable_type = self.class.name
      avg.qty = 1
      avg.avg = davg
      avg.dimension = dimension
    end
  else
    a = average(dimension)
    a.qty = rates(dimension).count
    a.avg = davg
    a.save!(validate: false)
  end
end