acts_rateable 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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