ratyrate 1.2.0.alpha

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.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +8 -0
  5. data/Gemfile.lock +51 -0
  6. data/README.md +169 -0
  7. data/Rakefile +12 -0
  8. data/lib/generators/ratyrate/USAGE +0 -0
  9. data/lib/generators/ratyrate/ratyrate_generator.rb +56 -0
  10. data/lib/generators/ratyrate/templates/average_cache_migration.rb +17 -0
  11. data/lib/generators/ratyrate/templates/average_cache_model.rb +4 -0
  12. data/lib/generators/ratyrate/templates/big-star.png +0 -0
  13. data/lib/generators/ratyrate/templates/cache_migration.rb +19 -0
  14. data/lib/generators/ratyrate/templates/cache_model.rb +3 -0
  15. data/lib/generators/ratyrate/templates/cancel-off.png +0 -0
  16. data/lib/generators/ratyrate/templates/cancel-on.png +0 -0
  17. data/lib/generators/ratyrate/templates/jquery.raty.js +464 -0
  18. data/lib/generators/ratyrate/templates/mid-star.png +0 -0
  19. data/lib/generators/ratyrate/templates/migration.rb +20 -0
  20. data/lib/generators/ratyrate/templates/model.rb +7 -0
  21. data/lib/generators/ratyrate/templates/overall_average_migration.rb +16 -0
  22. data/lib/generators/ratyrate/templates/overall_average_model.rb +4 -0
  23. data/lib/generators/ratyrate/templates/rater_controller.rb +13 -0
  24. data/lib/generators/ratyrate/templates/ratyrate.js.erb +59 -0
  25. data/lib/generators/ratyrate/templates/star-half.png +0 -0
  26. data/lib/generators/ratyrate/templates/star-off.png +0 -0
  27. data/lib/generators/ratyrate/templates/star-on.png +0 -0
  28. data/lib/ratyrate/helpers.rb +144 -0
  29. data/lib/ratyrate/model.rb +153 -0
  30. data/lib/ratyrate/version.rb +3 -0
  31. data/lib/ratyrate.rb +7 -0
  32. data/ratyrate.gemspec +24 -0
  33. metadata +76 -0
@@ -0,0 +1,144 @@
1
+ module Helpers
2
+ def rating_for(rateable_obj, dimension=nil, options={})
3
+
4
+ cached_average = rateable_obj.average dimension
5
+ avg = cached_average ? cached_average.avg : 0
6
+
7
+ star = options[:star] || 5
8
+ enable_half = options[:enable_half] || true
9
+ half_show = options[:half_show] || true
10
+ star_path = options[:star_path] || "/assets"
11
+ star_on = options[:star_on] || "star-on.png"
12
+ star_off = options[:star_off] || "star-off.png"
13
+ star_half = options[:star_half] || "star-half.png"
14
+ cancel = options[:cancel] || false
15
+ cancel_place = options[:cancel_place] || "left"
16
+ cancel_hint = options[:cancel_hint] || "Cancel current rating!"
17
+ cancel_on = options[:cancel_on] || "cancel-on.png"
18
+ cancel_off = options[:cancel_off] || "cancel-off.png"
19
+ noRatedMsg = options[:noRatedMsg] || "I'am readOnly and I haven't rated yet!"
20
+ # round = options[:round] || { down: .26, full: .6, up: .76 }
21
+ space = options[:space] || false
22
+ single = options[:single] || false
23
+ target = options[:target] || ''
24
+ targetText = options[:targetText] || ''
25
+ targetType = options[:targetType] || 'hint'
26
+ targetFormat = options[:targetFormat] || '{score}'
27
+ targetScore = options[:targetScore] || ''
28
+
29
+ disable_after_rate = options[:disable_after_rate] && true
30
+ disable_after_rate = true if disable_after_rate == nil
31
+
32
+ if disable_after_rate
33
+ readonly = !(current_user && rateable_obj.can_rate?(current_user, dimension))
34
+ else
35
+ readonly = false
36
+ end
37
+
38
+ if options[:imdb_avg] && readonly
39
+ content_tag :div, '', :style => "background-image:url(/assets/mid-star.png);width:61px;height:57px;margin-top:10px;" do
40
+ content_tag :p, avg, :style => "position:relative;font-size:.8rem;text-align:center;line-height:60px;"
41
+ end
42
+ else
43
+ content_tag :div, '', "data-dimension" => dimension, :class => "star", "data-rating" => avg,
44
+ "data-id" => rateable_obj.id, "data-classname" => rateable_obj.class.name,
45
+ "data-disable-after-rate" => disable_after_rate,
46
+ "data-readonly" => readonly,
47
+ "data-enable-half" => enable_half,
48
+ "data-half-show" => half_show,
49
+ "data-star-count" => star,
50
+ "data-star-path" => star_path,
51
+ "data-star-on" => star_on,
52
+ "data-star-off" => star_off,
53
+ "data-star-half" => star_half,
54
+ "data-cancel" => cancel,
55
+ "data-cancel-place" => cancel_place,
56
+ "data-cancel-hint" => cancel_hint,
57
+ "data-cancel-on" => cancel_on,
58
+ "data-cancel-off" => cancel_off,
59
+ "data-no-rated-message" => noRatedMsg,
60
+ # "data-round" => round,
61
+ "data-space" => space,
62
+ "data-single" => single,
63
+ "data-target" => target,
64
+ "data-target-text" => targetText,
65
+ "data-target-type" => targetType,
66
+ "data-target-format" => targetFormat,
67
+ "data-target-score" => targetScore
68
+ end
69
+ end
70
+
71
+ def imdb_style_rating_for(rateable_obj, user, options = {})
72
+ overall_avg = rateable_obj.overall_avg(user)
73
+
74
+ content_tag :div, '', :style => "background-image:url(/assets/big-star.png);width:81px;height:81px;margin-top:10px;" do
75
+ content_tag :p, overall_avg, :style => "position:relative;line-height:85px;text-align:center;"
76
+ end
77
+ end
78
+
79
+ def rating_for_user(rateable_obj, rating_user, dimension = nil, options = {})
80
+ @object = rateable_obj
81
+ @user = rating_user
82
+ @rating = Rate.find_by_rater_id_and_rateable_id_and_dimension(@user.id, @object.id, dimension)
83
+ stars = @rating ? @rating.stars : 0
84
+
85
+ star = options[:star] || 5
86
+ enable_half = options[:enable_half] || true
87
+ half_show = options[:half_show] || true
88
+ star_path = options[:star_path] || "/assets"
89
+ star_on = options[:star_on] || "star-on.png"
90
+ star_off = options[:star_off] || "star-off.png"
91
+ star_half = options[:star_half] || "star-half.png"
92
+ cancel = options[:cancel] || false
93
+ cancel_place = options[:cancel_place] || "left"
94
+ cancel_hint = options[:cancel_hint] || "Cancel current rating!"
95
+ cancel_on = options[:cancel_on] || "cancel-on.png"
96
+ cancel_off = options[:cancel_off] || "cancel-off.png"
97
+ noRatedMsg = options[:noRatedMsg] || "I'am readOnly and I haven't rated yet!"
98
+ # round = options[:round] || { down: .26, full: .6, up: .76 }
99
+ space = options[:space] || false
100
+ single = options[:single] || false
101
+ target = options[:target] || ''
102
+ targetText = options[:targetText] || ''
103
+ targetType = options[:targetType] || 'hint'
104
+ targetFormat = options[:targetFormat] || '{score}'
105
+ targetScore = options[:targetScore] || ''
106
+
107
+ disable_after_rate = options[:disable_after_rate] || false
108
+
109
+ readonly=false
110
+ if disable_after_rate
111
+ readonly = current_user.present? ? !rateable_obj.can_rate?(current_user.id, dimension) : true
112
+ end
113
+
114
+ content_tag :div, '', "data-dimension" => dimension, :class => "star", "data-rating" => stars,
115
+ "data-id" => rateable_obj.id, "data-classname" => rateable_obj.class.name,
116
+ "data-disable-after-rate" => disable_after_rate,
117
+ "data-readonly" => readonly,
118
+ "data-enable-half" => enable_half,
119
+ "data-half-show" => half_show,
120
+ "data-star-count" => stars,
121
+ "data-star-path" => star_path,
122
+ "data-star-on" => star_on,
123
+ "data-star-off" => star_off,
124
+ "data-star-half" => star_half,
125
+ "data-cancel" => cancel,
126
+ "data-cancel-place" => cancel_place,
127
+ "data-cancel-hint" => cancel_hint,
128
+ "data-cancel-on" => cancel_on,
129
+ "data-cancel-off" => cancel_off,
130
+ "data-no-rated-message" => noRatedMsg,
131
+ # "data-round" => round,
132
+ "data-space" => space,
133
+ "data-single" => single,
134
+ "data-target" => target,
135
+ "data-target-text" => targetText,
136
+ "data-target-format" => targetFormat,
137
+ "data-target-score" => targetScore
138
+ end
139
+
140
+ end
141
+
142
+ class ActionView::Base
143
+ include Helpers
144
+ end
@@ -0,0 +1,153 @@
1
+ require 'active_support/concern'
2
+ module Ratyrate
3
+ extend ActiveSupport::Concern
4
+
5
+ def rate(stars, user, dimension=nil, dirichlet_method=false)
6
+ dimension = nil if dimension.blank?
7
+
8
+ if can_rate? user, dimension
9
+ rates(dimension).create! do |r|
10
+ r.stars = stars
11
+ r.rater = user
12
+ end
13
+ if dirichlet_method
14
+ update_rate_average_dirichlet(stars, dimension)
15
+ else
16
+ update_rate_average(stars, dimension)
17
+ end
18
+ else
19
+ update_current_rate(stars, user, dimension)
20
+ end
21
+ end
22
+
23
+ def update_rate_average_dirichlet(stars, dimension=nil)
24
+ ## assumes 5 possible vote categories
25
+ dp = {1 => 1, 2 => 1, 3 => 1, 4 => 1, 5 => 1}
26
+ stars_group = Hash[rates(dimension).group(:stars).count.map{|k,v| [k.to_i,v] }]
27
+ posterior = dp.merge(stars_group){|key, a, b| a + b}
28
+ sum = posterior.map{ |i, v| v }.inject { |a, b| a + b }
29
+ davg = posterior.map{ |i, v| i * v }.inject { |a, b| a + b }.to_f / sum
30
+
31
+ if average(dimension).nil?
32
+ RatingCache.create! do |avg|
33
+ avg.cacheable_id = self.id
34
+ avg.cacheable_type = self.class.name
35
+ avg.qty = 1
36
+ avg.avg = davg
37
+ avg.dimension = dimension
38
+ end
39
+ else
40
+ a = average(dimension)
41
+ a.qty = rates(dimension).count
42
+ a.avg = davg
43
+ a.save!(validate: false)
44
+ end
45
+ end
46
+
47
+ def update_rate_average(stars, dimension=nil)
48
+ if average(dimension).nil?
49
+ RatingCache.create! do |avg|
50
+ avg.cacheable_id = self.id
51
+ avg.cacheable_type = self.class.name
52
+ avg.avg = stars
53
+ avg.qty = 1
54
+ avg.dimension = dimension
55
+ end
56
+ else
57
+ a = average(dimension)
58
+ a.qty = rates(dimension).count
59
+ a.avg = rates(dimension).average(:stars)
60
+ a.save!(validate: false)
61
+ end
62
+ end
63
+
64
+ def update_current_rate(stars, user, dimension)
65
+ current_rate = user.ratings_given.where(rater_id: user.id, rateable_id: self.id, dimension: dimension).take
66
+ current_rate.stars = stars
67
+ current_rate.save!(validate: false)
68
+
69
+ if rates(dimension).count > 1
70
+ update_rate_average(stars, dimension)
71
+ else # Set the avarage to the exact number of stars
72
+ a = average(dimension)
73
+ a.avg = stars
74
+ a.save!(validate: false)
75
+ end
76
+ end
77
+
78
+ def overall_avg(user)
79
+ # avg = OverallAverage.where(rateable_id: self.id)
80
+ # #FIXME: Fix the bug when the movie has no ratings
81
+ # unless avg.empty?
82
+ # return avg.take.avg unless avg.take.avg == 0
83
+ # else # calculate average, and save it
84
+ # dimensions_count = overall_score = 0
85
+ # user.ratings_given.select('DISTINCT dimension').each do |d|
86
+ # dimensions_count = dimensions_count + 1
87
+ # unless average(d.dimension).nil?
88
+ # overall_score = overall_score + average(d.dimension).avg
89
+ # end
90
+ # end
91
+ # overall_avg = (overall_score / dimensions_count).to_f.round(1)
92
+ # AverageCache.create! do |a|
93
+ # a.rater_id = user.id
94
+ # a.rateable_id = self.id
95
+ # a.avg = overall_avg
96
+ # end
97
+ # overall_avg
98
+ # end
99
+ end
100
+
101
+ # calculate the movie overall average rating for all users
102
+ def calculate_overall_average
103
+ end
104
+
105
+ def average(dimension=nil)
106
+ dimension ? self.send("#{dimension}_average") : rate_average_without_dimension
107
+ end
108
+
109
+ def can_rate?(user, dimension=nil)
110
+ user.ratings_given.where(dimension: dimension, rateable_id: id, rateable_type: self.class.name).size.zero?
111
+ end
112
+
113
+ def rates(dimension=nil)
114
+ dimension ? self.send("#{dimension}_rates") : rates_without_dimension
115
+ end
116
+
117
+ def raters(dimension=nil)
118
+ dimension ? self.send("#{dimension}_raters") : raters_without_dimension
119
+ end
120
+
121
+ module ClassMethods
122
+
123
+ def ratyrate_rater
124
+ has_many :ratings_given, :class_name => "Rate", :foreign_key => :rater_id
125
+ end
126
+
127
+ def ratyrate_rateable(*dimensions)
128
+ has_many :rates_without_dimension, -> { where dimension: nil}, :as => :rateable, :class_name => "Rate", :dependent => :destroy
129
+ has_many :raters_without_dimension, :through => :rates_without_dimension, :source => :rater
130
+
131
+ has_one :rate_average_without_dimension, -> { where dimension: nil}, :as => :cacheable,
132
+ :class_name => "RatingCache", :dependent => :destroy
133
+
134
+ dimensions.each do |dimension|
135
+ has_many "#{dimension}_rates".to_sym, -> {where dimension: dimension.to_s},
136
+ :dependent => :destroy,
137
+ :class_name => "Rate",
138
+ :as => :rateable
139
+
140
+ has_many "#{dimension}_raters".to_sym, :through => "#{dimension}_rates", :source => :rater
141
+
142
+ has_one "#{dimension}_average".to_sym, -> { where dimension: dimension.to_s },
143
+ :as => :cacheable, :class_name => "RatingCache",
144
+ :dependent => :destroy
145
+ end
146
+ end
147
+ end
148
+
149
+ end
150
+
151
+ class ActiveRecord::Base
152
+ include Ratyrate
153
+ end
@@ -0,0 +1,3 @@
1
+ module Ratyrate
2
+ VERSION = "1.2.0.alpha"
3
+ end
data/lib/ratyrate.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "ratyrate/version"
2
+ require "ratyrate/model"
3
+ require "ratyrate/helpers"
4
+
5
+ module Ratyrate
6
+
7
+ end
data/ratyrate.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ratyrate/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ratyrate"
7
+ s.version = Ratyrate::VERSION
8
+ s.authors = ["Islam Wazery"]
9
+ s.email = ["wazery@ubuntu.com"]
10
+ s.homepage = "http://github.com/wazery/ratyrate"
11
+ s.summary = %q{A Ruby Gem that provides the same functionality of jQuery Raty library, and adds IMDB style rating.}
12
+ s.description = %q{A Ruby Gem that provides the same functionality of jQuery Raty library, and adds IMDB style rating.}
13
+
14
+ s.rubyforge_project = "ratyrate"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ratyrate
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0.alpha
5
+ platform: ruby
6
+ authors:
7
+ - Islam Wazery
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-09 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A Ruby Gem that provides the same functionality of jQuery Raty library,
14
+ and adds IMDB style rating.
15
+ email:
16
+ - wazery@ubuntu.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".gitignore"
22
+ - ".travis.yml"
23
+ - Gemfile
24
+ - Gemfile.lock
25
+ - README.md
26
+ - Rakefile
27
+ - lib/generators/ratyrate/USAGE
28
+ - lib/generators/ratyrate/ratyrate_generator.rb
29
+ - lib/generators/ratyrate/templates/average_cache_migration.rb
30
+ - lib/generators/ratyrate/templates/average_cache_model.rb
31
+ - lib/generators/ratyrate/templates/big-star.png
32
+ - lib/generators/ratyrate/templates/cache_migration.rb
33
+ - lib/generators/ratyrate/templates/cache_model.rb
34
+ - lib/generators/ratyrate/templates/cancel-off.png
35
+ - lib/generators/ratyrate/templates/cancel-on.png
36
+ - lib/generators/ratyrate/templates/jquery.raty.js
37
+ - lib/generators/ratyrate/templates/mid-star.png
38
+ - lib/generators/ratyrate/templates/migration.rb
39
+ - lib/generators/ratyrate/templates/model.rb
40
+ - lib/generators/ratyrate/templates/overall_average_migration.rb
41
+ - lib/generators/ratyrate/templates/overall_average_model.rb
42
+ - lib/generators/ratyrate/templates/rater_controller.rb
43
+ - lib/generators/ratyrate/templates/ratyrate.js.erb
44
+ - lib/generators/ratyrate/templates/star-half.png
45
+ - lib/generators/ratyrate/templates/star-off.png
46
+ - lib/generators/ratyrate/templates/star-on.png
47
+ - lib/ratyrate.rb
48
+ - lib/ratyrate/helpers.rb
49
+ - lib/ratyrate/model.rb
50
+ - lib/ratyrate/version.rb
51
+ - ratyrate.gemspec
52
+ homepage: http://github.com/wazery/ratyrate
53
+ licenses: []
54
+ metadata: {}
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.3.1
69
+ requirements: []
70
+ rubyforge_project: ratyrate
71
+ rubygems_version: 2.2.2
72
+ signing_key:
73
+ specification_version: 4
74
+ summary: A Ruby Gem that provides the same functionality of jQuery Raty library, and
75
+ adds IMDB style rating.
76
+ test_files: []