Class: Workarea::Review

Inherits:
Object
  • Object
show all
Includes:
ApplicationDocument
Defined in:
app/models/workarea/review.rb,
app/models/workarea/review/request.rb

Defined Under Namespace

Classes: Request

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.find_aggregates(*product_ids) ⇒ Hash

Lookup aggregate review stats on multiple products. Used for show stats on browse/detail.

Parameters:

  • product_ids (Array<String>)

Returns:

  • (Hash)

    results Keys are product IDs, values are stats Hash



75
76
77
78
79
80
81
82
83
84
85
86
# File 'app/models/workarea/review.rb', line 75

def self.find_aggregates(*product_ids)
  product_ids = Array(product_ids).flatten

  if product_ids.one?
    find_single_aggregates(product_ids.first)
  else
    product_ids.inject({}) do |memo, product_id|
      memo[product_id] = find_single_aggregates(product_id)
      memo
    end
  end
end

.find_for_product(product_id, allow_unapproved = false) ⇒ Mongoid::Criteria

Get Mongoid::Criteria for the reviews for a certain product. Optionally allow including unapproved reviews (for the admin).

Parameters:

  • product_id (String)
  • allow_unapproved (optional, Boolean) (defaults to: false)

Returns:

  • (Mongoid::Criteria)


54
55
56
57
# File 'app/models/workarea/review.rb', line 54

def self.find_for_product(product_id, allow_unapproved = false)
  criteria = by_product(product_id)
  allow_unapproved ? criteria : criteria.approved
end

.find_single_aggregates(product_id) ⇒ Hash

Lookup aggregate stats on product reviews for a product.

Parameters:

  • product_id (String)

Returns:

  • (Hash)


64
65
66
67
# File 'app/models/workarea/review.rb', line 64

def self.find_single_aggregates(product_id)
  stats = by_product(product_id).approved.aggregates(:rating)
  { count: stats['count'] || 0, average: stats['avg'] || 0 }
end

.find_sorting_score(product_id) ⇒ Float

Find sort score for a product. Used in the search index for sorting by best reviewed.

Balances a small number of ratings with the uncertainty of only having a few ratings. See: http://masanjin.net/blog/how-to-rank-products-based-on-user-input

Parameters:

  • product_id (String)

Returns:

  • (Float)


97
98
99
100
101
102
103
104
# File 'app/models/workarea/review.rb', line 97

def self.find_sorting_score(product_id)
  reviews = find_for_product(product_id).to_a
  count = (1..5).each_with_object({}) do |i, memo|
    memo[i] = reviews.select { |r| r.rating == i }.length + 2
  end

  count.sum { |rating, count| rating * count }.to_f / count.values.sum
end

.sortsObject



39
40
41
42
43
44
45
# File 'app/models/workarea/review.rb', line 39

def self.sorts
  [ Workarea::Sort.pending,
    Workarea::Sort.newest,
    Workarea::Sort.modified,
    Workarea::Sort.title,
    Workarea::Sort.rating ]
end

Instance Method Details

#anonymous?Boolean

Returns:

  • (Boolean)


106
107
108
# File 'app/models/workarea/review.rb', line 106

def anonymous?
  !user_id.present?
end

#ensure_titleObject



110
111
112
# File 'app/models/workarea/review.rb', line 110

def ensure_title
  self.title = body.truncate(50) if title.blank?
end

#user_must_have_spent_money_to_create_reviewObject



114
115
116
117
118
119
120
121
122
# File 'app/models/workarea/review.rb', line 114

def user_must_have_spent_money_to_create_review
  if Workarea.config.require_purchase_to_post_review
    user = User.find(user_id)
    if user.total_spent.to_f.zero?
      err_msg = I18n.t('workarea.storefront.reviews.total_spent_validation')
      errors.add(:user, err_msg)
    end
  end
end