acts_rateable 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2013 YOURNAME
1
+ Copyright 2013 TY RAUBER
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/lib/acts_rateable.rb CHANGED
@@ -2,4 +2,6 @@ require 'rubygems'
2
2
  require 'acts_rateable/version'
3
3
  require 'acts_rateable/acts_rateable'
4
4
  require 'acts_rateable/rate.rb'
5
- require 'acts_rateable/rating.rb'
5
+ require 'acts_rateable/ar_rating.rb'
6
+ require 'acts_rateable/rating.rb'
7
+ require 'acts_rateable/count.rb'
@@ -11,13 +11,19 @@ module ActsRateable
11
11
  has_many :rates, class_name: ActsRateable::Rate, as: :resource, dependent: :destroy
12
12
  has_many :rated, class_name: ActsRateable::Rate, as: :author, dependent: :destroy
13
13
  has_one :rating, class_name: ActsRateable::Rating, as: :resource, dependent: :destroy
14
+ has_one :count, class_name: ActsRateable::Count, as: :resource, dependent: :destroy
14
15
 
15
16
  scope :order_by_rating, lambda { | column='estimate', direction="DESC" |
16
17
  includes(:rating).group('ar_ratings.id').order("ar_ratings.#{column.downcase} #{direction.upcase}")
17
18
  }
18
19
 
20
+ scope :order_by_count, lambda { | column='estimate', direction="DESC" |
21
+ includes(:count).group('ar_ratings.id').order("ar_ratings.#{column.downcase} #{direction.upcase}")
22
+ }
23
+
19
24
  after_save do
20
- ActsRateable::Rating.where({resource_id: self.id, resource_type: self.class.name}).first_or_create #if !rates.empty?
25
+ ActsRateable::Rating.where({resource_id: self.id, resource_type: self.class.name}).first_or_initialize.save #if !rates.empty?
26
+ ActsRateable::Count.where({resource_id: self.id, resource_type: self.class.name}).first_or_initialize.save #if !rates.empty?
21
27
  end
22
28
 
23
29
  include LocalInstanceMethods
@@ -0,0 +1,5 @@
1
+ module ActsRateable
2
+ class ArRating < ActiveRecord::Base
3
+
4
+ end
5
+ end
@@ -0,0 +1,56 @@
1
+ module ActsRateable
2
+ class Count < ActsRateable::ArRating
3
+
4
+ belongs_to :resource, polymorphic: true
5
+ # has_many :rates, through: :counts, as: :author
6
+
7
+ attr_accessible :resource_id, :resource_type, :total, :sum, :average, :estimate, :type
8
+
9
+ validates :resource, :total, :sum, :average, :estimate, presence: true
10
+ validates_numericality_of :total, :sum, :average, :estimate
11
+
12
+ @@global_counts = {}
13
+
14
+ before_save :update_ratings
15
+
16
+ def self.set_totals(author)
17
+ sql = "SELECT COUNT(*) total_ratings, SUM(value) rating_sum, AVG(value) rating_avg, "+
18
+ "(SELECT COUNT(DISTINCT author_id) FROM ar_rates WHERE author_type = '#{author.class.name}') rated_count, "+
19
+ "((SELECT COUNT(*) from ar_rates WHERE author_type = '#{author.class.name}') / (SELECT COUNT(DISTINCT author_id) FROM ar_rates WHERE author_type = '#{author.class.name}')) avg_num_ratings "+
20
+ "FROM ar_rates WHERE author_type = '#{author.class.name}'"
21
+ @@global_counts[author.class.name] = ActsRateable::Rate.connection.execute(sql).first
22
+ end
23
+
24
+ # RETURNS = { "total_ratings"=>"", "rating_sum"=>"", "rating_avg"=>"", "rated_count"=>"", "avg_num_ratings"=>"" }
25
+ def self.get_totals(author)
26
+ @@global_counts[author.class.name] ||= set_totals(author)
27
+ end
28
+
29
+ # RETURNS = {"total_ratings"=>"", "rating_sum"=>"", "rating_avg"=>""}
30
+ def self.values_for(author)
31
+ sql = "SELECT COUNT(*) total_ratings, COALESCE(SUM(value),0) rating_sum, COALESCE(AVG(value),0) rating_avg "+
32
+ "FROM ar_rates WHERE author_type = '#{author.class.name}' and author_id = '#{author.id}'"
33
+ ActsRateable::Rate.connection.execute(sql).first
34
+ end
35
+
36
+ def self.data_for(author)
37
+ local = values_for(author)
38
+ global = get_totals(author)
39
+ estimate = (local['total_ratings'].to_f / (local['total_ratings'].to_f+global['avg_num_ratings'].to_f)) * local['rating_avg'].to_f + (global['avg_num_ratings'].to_f / (local['total_ratings'].to_f+global['avg_num_ratings'].to_f)) *global['rating_avg'].to_f
40
+ return { 'global' => global, 'local' => local.merge!({ 'estimate' => estimate }) }
41
+ end
42
+
43
+ protected
44
+
45
+ def update_ratings
46
+ if resource && !resource.rated.empty?
47
+ result = self.class.data_for(resource)
48
+ self.total = result['local']['total_ratings']
49
+ self.average = result['local']['rating_avg']
50
+ self.sum = result['local']['rating_sum']
51
+ self.estimate = result['local']['estimate']
52
+ self.class.set_totals(resource) # Reset global values
53
+ end
54
+ end
55
+ end
56
+ end
@@ -40,7 +40,8 @@ module ActsRateable
40
40
  private
41
41
 
42
42
  def generate_estimate
43
- ActsRateable::Rating.create({resource_id: resource.id, resource_type: resource.class.name})
43
+ ActsRateable::Rating.where({resource_id: self.resource_id, resource_type: self.resource_type}).first_or_initialize.save #if !rates.empty?
44
+ ActsRateable::Count.where({resource_id: self.author_id, resource_type: self.author_type}).first_or_initialize.save #if !rates.empty?
44
45
  end
45
46
  end
46
47
  end
@@ -1,12 +1,10 @@
1
1
  module ActsRateable
2
- class Rating < ActiveRecord::Base
3
-
4
- self.table_name = "ar_ratings"
5
-
2
+ class Rating < ActsRateable::ArRating
3
+
6
4
  belongs_to :resource, polymorphic: true
7
- has_many :rates, through: :ratings, as: :resource
5
+ #has_many :rates, through: :ratings, as: :resource
8
6
 
9
- attr_accessible :resource_id, :resource_type, :total, :sum, :average, :estimate
7
+ attr_accessible :resource_id, :resource_type, :total, :sum, :average, :estimate, :type
10
8
 
11
9
  validates :resource, :total, :sum, :average, :estimate, presence: true
12
10
  validates_numericality_of :total, :sum, :average, :estimate
@@ -45,7 +43,7 @@ module ActsRateable
45
43
  protected
46
44
 
47
45
  def update_ratings
48
- if !resource.rates.empty?
46
+ if resource && !resource.rates.empty?
49
47
  result = self.class.data_for(resource)
50
48
  self.total = result['local']['total_ratings']
51
49
  self.average = result['local']['rating_avg']
@@ -1,3 +1,3 @@
1
1
  module ActsRateable
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -12,6 +12,7 @@ class ActsRateableMigration < ActiveRecord::Migration
12
12
 
13
13
  create_table :ar_ratings do |t|
14
14
  t.references :resource, :polymorphic => true, :null => false
15
+ t.string :type
15
16
  t.integer :total, :default => 0
16
17
  t.integer :sum, :default => 0
17
18
  t.decimal :average, :default => 0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_rateable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-29 00:00:00.000000000 Z
12
+ date: 2013-06-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -51,6 +51,8 @@ extensions: []
51
51
  extra_rdoc_files: []
52
52
  files:
53
53
  - lib/acts_rateable/acts_rateable.rb
54
+ - lib/acts_rateable/ar_rating.rb
55
+ - lib/acts_rateable/count.rb
54
56
  - lib/acts_rateable/rate.rb
55
57
  - lib/acts_rateable/rating.rb
56
58
  - lib/acts_rateable/version.rb