seems_rateable 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MDIyYWVmMmNkMzAyNGI2MzcwNzdhZjdlNTA3ZWQ5MmFkNTcwNjgzOQ==
5
+ data.tar.gz: !binary |-
6
+ NThmYmIwN2M1OWNiY2Y3OGM2MzIyNDUyYTI5MTZmNmQyZGM4Yzc2OA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ZjViZTcyMDJjYzU3MTc0ZjhiZmI0ZGQxMzc1ZDBjMjVmNzUzZTMzNmMxNTQ1
10
+ YzA2ODYwNTlkMzVjMDQ4MzEwNGZmY2ViMjAxNTRhOTAyYWI5ZWU2YjFkMGE3
11
+ YzNmZmZjYTRlMjJhMDEyYWIxN2NiZjkyMmQ1OGQyYzk0NGVmNTE=
12
+ data.tar.gz: !binary |-
13
+ NWUxNDc0Y2Q5YjhkNGU2YzcwNWQ1Mjk5NGVkOGMxMzA3YmNkOGExMTdmZTFm
14
+ YTU4ODkzNmM2MmM4MjUyY2Q0ZTRlM2JhZThhODA3OTBjY2QwYmIxNGIxZWE2
15
+ MmJjODZjMDhiYWU5OTdiOGJiYjllYWE3NzM3MGMwMDcyNGM0NDE=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.project ADDED
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <projectDescription>
3
+ <name>seems_rateable</name>
4
+ <comment></comment>
5
+ <projects>
6
+ </projects>
7
+ <buildSpec>
8
+ <buildCommand>
9
+ <name>com.aptana.ide.core.unifiedBuilder</name>
10
+ <arguments>
11
+ </arguments>
12
+ </buildCommand>
13
+ </buildSpec>
14
+ <natures>
15
+ <nature>org.radrails.rails.core.railsnature</nature>
16
+ <nature>com.aptana.ruby.core.rubynature</nature>
17
+ </natures>
18
+ </projectDescription>
data/.rvmrc ADDED
File without changes
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+ # Specify your gem's dependencies in seems_rateable.gemspec
3
+ gemspec
4
+ group :test, :development do
5
+ gem 'factory_girl_rails', '~> 4.0'
6
+ gem 'rspec'
7
+ gem 'debugger'
8
+ gem 'shoulda-matchers'
9
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 progz
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # SeemsRateable
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'seems_rateable'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install seems_rateable
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => :spec
7
+ task :test => :spec
File without changes
@@ -0,0 +1,65 @@
1
+ require 'rails/generators/migration'
2
+ require 'fileutils'
3
+
4
+ class SeemsRateableGenerator < Rails::Generators::NamedBase
5
+ include Rails::Generators::Migration
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ desc "Copying asset files ..."
9
+ def assets
10
+ FileUtils.mkdir_p 'vendor/assets/images/rateable'
11
+ Dir::mkdir 'vendor/assets/stylesheets/rateable'
12
+ Dir::mkdir 'vendor/assets/javascripts/rateable'
13
+
14
+ copy_file 'images/bg_jRatingInfos.png', 'vendor/assets/images/rateable/bg_jRatingInfos.png'
15
+ copy_file 'images/small.png', 'vendor/assets/images/rateable/small.png'
16
+ copy_file 'images/stars.png', 'vendor/assets/images/rateable/stars.png'
17
+
18
+ copy_file 'stylesheets/jRating.jquery.css', 'vendor/assets/stylesheets/rateable/jRating.jquery.css'
19
+ copy_file 'javascripts/jRating.jquery.js.erb', 'vendor/assets/javascripts/rateable/jRating.jquery.js.erb'
20
+ copy_file 'javascripts/rateable.jquery.js.erb', 'vendor/assets/javascripts/rateable/rateable.jquery.js.erb'
21
+ end
22
+
23
+ desc "Generating controller file ..."
24
+ def controller
25
+ class_collisions 'RatingsController'
26
+ template "controller.rb", File.join('app/controllers', 'ratings_controller.rb')
27
+ end
28
+
29
+ desc "Generating model files ..."
30
+ def models
31
+ model_file = File.join('app/models', "#{file_path}.rb")
32
+ raise "User model (#{model_file}) must exits." unless File.exists?(model_file)
33
+ class_collisions 'Rate'
34
+ class_collisions 'CachedRating'
35
+ template 'model.rb', File.join('app/models', 'rate.rb')
36
+ template 'cached_model.rb', File.join('app/models', 'cached_rating.rb')
37
+ end
38
+
39
+ desc "Creating route ..."
40
+ def routegen
41
+ route "resources :ratings, :only => :create"
42
+ end
43
+
44
+ desc "Generating migrations ..."
45
+ def migrations
46
+ migration_template "cached_rating_migration.rb", "db/migrate/create_cached_ratings.rb"
47
+ migration_template "rate_migration.rb", "db/migrate/create_rates.rb"
48
+ end
49
+
50
+ desc "Creating needed database tables"
51
+ def migrating
52
+ rake("db:migrate")
53
+ end
54
+
55
+ private
56
+ def self.next_migration_number(dirname)
57
+ #if ActiveRecord::Base.timestamped_migrations
58
+ # Time.now.utc.strftime("%Y%m%d%H%M%S%L")
59
+ #else
60
+ "%.3d" % (current_migration_number(dirname) + 1)
61
+ #end
62
+ end
63
+
64
+ end
65
+
@@ -0,0 +1,4 @@
1
+ class CachedRating < ActiveRecord::Base
2
+ attr_accessible :avg, :dimension
3
+ belongs_to :cacheable, :polymorphic => true
4
+ end
@@ -0,0 +1,17 @@
1
+ class CreateCachedRatings < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :cached_ratings do |t|
4
+ t.belongs_to :cacheable, :polymorphic => true
5
+ t.float :avg, :null => false
6
+ t.integer :cnt, :null => false
7
+ t.string :dimension
8
+ t.integer :cacheable_id, :limit => 8
9
+ t.string :cacheable_type
10
+ t.timestamps
11
+ end
12
+ end
13
+
14
+ def self.down
15
+ drop_table :cached_ratings
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ class RatingsController < ApplicationController
2
+
3
+ def create
4
+ obj = eval "#{params[:kls]}.find(#{params[:idBox]})" rescue nil
5
+ if obj.nil?
6
+ raise "Object does not exist."
7
+ end
8
+
9
+ if obj && obj.rate(params[:rate].to_f, current_user.id, params[:dimension])
10
+ render :json => true
11
+ else
12
+ render :json => {:error => true}
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,225 @@
1
+ /************************************************************************
2
+ *************************************************************************
3
+ @Name : jRating - jQuery Plugin
4
+ @Revison : 3.0
5
+ @Date : 28/01/2013
6
+ @Author: ALPIXEL - (www.myjqueryplugins.com - www.alpixel.fr)
7
+ @License : Open Source - MIT License : http://www.opensource.org/licenses/mit-license.php
8
+
9
+ **************************************************************************
10
+ *************************************************************************/
11
+ (function($) {
12
+ $.fn.jRating = function(op) {
13
+ var defaults = {
14
+ /** String vars **/
15
+ bigStarsPath : '<%= image_path "rateable/stars.png" %>', // path of the icon stars.png
16
+ smallStarsPath : '<%= image_path "rateable/small.png" %>', // path of the icon small.png
17
+ path : '<%= Rails.application.class.routes.url_helpers.ratings_path %>', // path of the php file jRating.php
18
+ type : 'big', // can be set to 'small' or 'big'
19
+
20
+ /** Boolean vars **/
21
+ step:false, // if true, mouseover binded star by star,
22
+ isDisabled:false,
23
+ showRateInfo: false,
24
+ canRateAgain : false,
25
+
26
+ /** Integer vars **/
27
+ length:5, // number of star to display
28
+ decimalLength : 0, // number of decimals.. Max 3, but you can complete the function 'getNote'
29
+ rateMax : 20, // maximal rate - integer from 0 to 9999 (or more)
30
+ rateInfosX : -45, // relative position in X axis of the info box when mouseover
31
+ rateInfosY : 5, // relative position in Y axis of the info box when mouseover
32
+ nbRates : 1,
33
+
34
+ /** Functions **/
35
+ onSuccess : null,
36
+ onError : null
37
+ };
38
+
39
+ if(this.length>0)
40
+ return this.each(function() {
41
+ /*vars*/
42
+ var opts = $.extend(defaults, op),
43
+ newWidth = 0,
44
+ starWidth = 0,
45
+ starHeight = 0,
46
+ bgPath = '',
47
+ hasRated = false,
48
+ globalWidth = 0,
49
+ nbOfRates = opts.nbRates;
50
+
51
+ if($(this).hasClass('jDisabled') || opts.isDisabled)
52
+ var jDisabled = true;
53
+ else
54
+ var jDisabled = false;
55
+
56
+ getStarWidth();
57
+ $(this).height(starHeight);
58
+
59
+
60
+
61
+ var average = parseFloat($(this).attr('data-average')), // get the average of all rates
62
+ idBox = parseInt($(this).attr('data-id')), // get the id of the box
63
+ kls = $(this).attr('data-kls'),
64
+ dimension = $(this).attr('data-dimension'),
65
+ widthRatingContainer = starWidth*opts.length, // Width of the Container
66
+ widthColor = average/opts.rateMax*widthRatingContainer, // Width of the color Container
67
+ quotient =
68
+ $('<div>',
69
+ {
70
+ 'class' : 'jRatingColor',
71
+ css:{
72
+ width:widthColor
73
+ }
74
+ }).appendTo($(this)),
75
+
76
+ average =
77
+ $('<div>',
78
+ {
79
+ 'class' : 'jRatingAverage',
80
+ css:{
81
+ width:0,
82
+ top:- starHeight
83
+ }
84
+ }).appendTo($(this)),
85
+
86
+ jstar =
87
+ $('<div>',
88
+ {
89
+ 'class' : 'jStar',
90
+ css:{
91
+ width:widthRatingContainer,
92
+ height:starHeight,
93
+ top:- (starHeight*2),
94
+ background: 'url('+bgPath+') repeat-x'
95
+ }
96
+ }).appendTo($(this));
97
+
98
+ $(this).css({width: widthRatingContainer,overflow:'hidden',zIndex:1,position:'relative'});
99
+
100
+ if(!jDisabled)
101
+ $(this).unbind().bind({
102
+ mouseenter : function(e){
103
+ var realOffsetLeft = findRealLeft(this);
104
+ var relativeX = e.pageX - realOffsetLeft;
105
+ if (opts.showRateInfo)
106
+ var tooltip =
107
+ $('<p>',{
108
+ 'class' : 'jRatingInfos',
109
+ html : getNote(relativeX)+' <span class="maxRate">/ '+opts.rateMax+'</span>',
110
+ css : {
111
+ top: (e.pageY + opts.rateInfosY),
112
+ left: (e.pageX + opts.rateInfosX)
113
+ }
114
+ }).appendTo('body').show();
115
+ },
116
+ mouseover : function(e){
117
+ $(this).css('cursor','pointer');
118
+ },
119
+ mouseout : function(){
120
+ $(this).css('cursor','default');
121
+ if(hasRated) average.width(globalWidth);
122
+ else average.width(0);
123
+ },
124
+ mousemove : function(e){
125
+ var realOffsetLeft = findRealLeft(this);
126
+ var relativeX = e.pageX - realOffsetLeft;
127
+ if(opts.step) newWidth = Math.floor(relativeX/starWidth)*starWidth + starWidth;
128
+ else newWidth = relativeX;
129
+ average.width(newWidth);
130
+ if (opts.showRateInfo)
131
+ $("p.jRatingInfos")
132
+ .css({
133
+ left: (e.pageX + opts.rateInfosX)
134
+ })
135
+ .html(getNote(newWidth) +' <span class="maxRate">/ '+opts.rateMax+'</span>');
136
+ },
137
+ mouseleave : function(){
138
+ $("p.jRatingInfos").remove();
139
+ },
140
+ click : function(e){
141
+ var element = this;
142
+
143
+ /*set vars*/
144
+ hasRated = true;
145
+ globalWidth = newWidth;
146
+ nbOfRates--;
147
+
148
+ if(!opts.canRateAgain || parseInt(nbOfRates) <= 0) $(this).unbind().css('cursor','default').addClass('jDisabled');
149
+
150
+ if (opts.showRateInfo) $("p.jRatingInfos").fadeOut('fast',function(){$(this).remove();});
151
+ e.preventDefault();
152
+ var rate = getNote(newWidth);
153
+ average.width(newWidth);
154
+
155
+
156
+ $.post(defaults.path,
157
+ {
158
+ idBox : idBox,
159
+ rate : rate,
160
+ kls : kls,
161
+ dimension : dimension
162
+ /** action : 'rating' **/
163
+ },
164
+ function(data) {
165
+ if(!data.error)
166
+ {
167
+ /** Here you can display an alert box,
168
+ or use the jNotify Plugin :) http://www.myqjqueryplugins.com/jNotify
169
+ exemple : */
170
+ if(opts.onSuccess) opts.onSuccess( element, rate );
171
+ }
172
+ else
173
+ {
174
+
175
+ /** Here you can display an alert box,
176
+ or use the jNotify Plugin :) http://www.myqjqueryplugins.com/jNotify
177
+ exemple : */
178
+ if(opts.onError) opts.onError( element, rate );
179
+ }
180
+ },
181
+ 'json'
182
+ );
183
+ }
184
+ });
185
+
186
+ function getNote(relativeX) {
187
+ var noteBrut = parseFloat((relativeX*100/widthRatingContainer)*opts.rateMax/100);
188
+ switch(opts.decimalLength) {
189
+ case 1 :
190
+ var note = Math.round(noteBrut*10)/10;
191
+ break;
192
+ case 2 :
193
+ var note = Math.round(noteBrut*100)/100;
194
+ break;
195
+ case 3 :
196
+ var note = Math.round(noteBrut*1000)/1000;
197
+ break;
198
+ default :
199
+ var note = Math.round(noteBrut*1)/1;
200
+ }
201
+ return note;
202
+ };
203
+
204
+ function getStarWidth(){
205
+ switch(opts.type) {
206
+ case 'small' :
207
+ starWidth = 12; // width of the picture small.png
208
+ starHeight = 10; // height of the picture small.png
209
+ bgPath = opts.smallStarsPath;
210
+ break;
211
+ default :
212
+ starWidth = 23; // width of the picture stars.png
213
+ starHeight = 20; // height of the picture stars.png
214
+ bgPath = opts.bigStarsPath;
215
+ }
216
+ };
217
+
218
+ function findRealLeft(obj) {
219
+ if( !obj ) return 0;
220
+ return obj.offsetLeft + findRealLeft( obj.offsetParent );
221
+ };
222
+ });
223
+
224
+ }
225
+ })(jQuery);
@@ -0,0 +1,24 @@
1
+ $(document).ready(function(){
2
+ $(".rateable").jRating({
3
+ //default options displayed below ->
4
+
5
+ rateMax: 5, // //Maximal rate
6
+ length : 5, // //Number of stars
7
+ //decimalLength : 0 //Number of decimals in the rate
8
+ //type : big, //Big or small
9
+ //step : true, //If set to true, filling of the stars is done star by star (step by step).
10
+ //isDisabled: false, //Set true to display static rating
11
+ //showRateInfo:false //Rate info panel, set true to display
12
+ //rateInfosX : 45 //In pixel - Absolute left position of the information box during mousemove.
13
+ //rateInfosY : 5 //In pixel - Absolute top position of the information box during mousemove.
14
+ path : '<%= Rails.application.class.routes.url_helpers.ratings_path %>',
15
+ onSuccess : function(element, rate){
16
+ //something like ->
17
+ alert('success');
18
+ },
19
+ onError : function(element, rate) {
20
+ alert('error')
21
+ }
22
+ });
23
+
24
+ });
@@ -0,0 +1,7 @@
1
+ class Rate < ActiveRecord::Base
2
+ belongs_to :rater, :class_name => "<%= file_name.classify %>"
3
+ belongs_to :rateable, :polymorphic => true
4
+
5
+ attr_accessible :stars, :dimension
6
+
7
+ end
@@ -0,0 +1,21 @@
1
+ class CreateRates < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :rates do |t|
4
+ t.belongs_to :rater
5
+ t.belongs_to :rateable, :polymorphic => true
6
+ t.float :stars, :null => false
7
+ t.integer :rater_id, :limit => 8
8
+ t.integer :rateable_id
9
+ t.string :rateable_type
10
+ t.string :dimension
11
+ t.timestamps
12
+ end
13
+
14
+ #add_index :rates, :rater_id
15
+ #add_index :rates, [:rateable_id, :rateable_type]
16
+ end
17
+
18
+ def self.down
19
+ drop_table :rates
20
+ end
21
+ end
@@ -0,0 +1,48 @@
1
+ /*********************/
2
+ /** jRating CSS **/
3
+ /*********************/
4
+
5
+ /**Div containing the color of the stars */
6
+
7
+
8
+ .jRatingAverage {
9
+ background-color:#f62929;
10
+ position:relative;
11
+ top:0;
12
+ left:0;
13
+ z-index:2;
14
+ height:100%;
15
+ }
16
+ .jRatingColor {
17
+ background-color:#FFD400; /* bgcolor of the stars*/
18
+ position:relative;
19
+ top:0;
20
+ left:0;
21
+ z-index:2;
22
+ height:100%;
23
+ }
24
+
25
+ /** Div containing the stars **/
26
+ .jStar {
27
+ position:relative;
28
+ left:0;
29
+ z-index:3;
30
+ }
31
+
32
+ /** P containing the rate informations **/
33
+ p.jRatingInfos {
34
+ position: absolute;
35
+ z-index:9999;
36
+ background: transparent url('bg_jRatingInfos.png') no-repeat;
37
+ color: #CACACA;
38
+ display: none;
39
+ width: 91px;
40
+ height: 29px;
41
+ font-size:16px;
42
+ text-align:center;
43
+ padding-top:5px;
44
+ }
45
+ p.jRatingInfos span.maxRate {
46
+ color:#c9c9c9;
47
+ font-size:14px;
48
+ }
@@ -0,0 +1,22 @@
1
+ module Helpers
2
+ def seems_rateable_style
3
+ stylesheet_link_tag "rateable/jRating.jquery"
4
+ end
5
+
6
+ def rating_for(obj, opts={:dimension => nil, :static => false})
7
+ begin
8
+ kls = opts[:dimension].nil? ? obj.average : obj.average(opts[:dimension])
9
+ avg = kls ? kls.avg : 0
10
+ content_tag :div, "", "data-average" => avg,
11
+ :class => "rateable#{opts[:static] ? " jDisabled" : nil}#{current_user ? nil : " jDisabled"}",
12
+ "data-id" => obj.id, "data-kls" => obj.class.name,
13
+ "data-dimension" => opts[:dimension]#, "data-size" => "small"
14
+ rescue StandardError => error
15
+ eval "raise 'Rateable object #{obj.inspect} does not exist'"
16
+ end
17
+ end
18
+ end
19
+
20
+ class ActionView::Base
21
+ include Helpers
22
+ end
@@ -0,0 +1,117 @@
1
+ require 'active_support/concern'
2
+ module SeemsRateable
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ def rate(stars, user_id, dimension = nil)
7
+ if update_permission && !permission(user_id, dimension)
8
+ allow_update_average stars, user_id, dimension
9
+ else
10
+ rate_cannot_update stars, user_id, dimension
11
+ end
12
+ end
13
+
14
+ def rate_cannot_update(stars, user_id, dimension = nil)
15
+ if permission user_id, dimension
16
+ rates(dimension).build do |r|
17
+ r.stars = stars
18
+ r.rater_id = user_id
19
+ r.save!
20
+ end
21
+ update_average(stars, dimension)
22
+ else
23
+ #raise "User has already voted."
24
+ return false
25
+ end
26
+ end
27
+
28
+ def update_average(stars, dimension=nil)
29
+ if average(dimension).nil?
30
+ CachedRating.create(:avg => stars, :dimension => dimension) do |r|
31
+ r.cacheable_id = self.id
32
+ r.cacheable_type = self.class.name
33
+ r.cnt = 1
34
+ end
35
+ else
36
+ r = average(dimension)
37
+ r.avg = (r.avg * r.cnt + stars) / (r.cnt+1)
38
+ r.cnt += 1
39
+ r.save!
40
+ end
41
+ end
42
+
43
+ def allow_update_average(stars, user_id, dimension=nil)
44
+ obj = rates(dimension).where(:rater_id => user_id, :dimension => dimension).first!
45
+ r = average(dimension)
46
+ r.avg = (r.avg*r.cnt - obj.stars + stars) / (r.cnt)
47
+ r.save!
48
+ obj.stars = stars
49
+ obj.save!
50
+ end
51
+
52
+
53
+ def average(dimension=nil)
54
+ if dimension.nil?
55
+ self.send "rate_average_without_dimension"
56
+ else
57
+ self.send "#{dimension}_average"
58
+ end
59
+ end
60
+
61
+ def permission(user_id, dimension=nil)
62
+ #record = connection.select_one("SELECT id FROM rates WHERE rateable_id=#{self.id} and rateable_type='#{self.class.name}' and rater_id=#{user_id} and dimension#{dimension ? "='#{dimension.to_s}'" : " IS NULL"}")
63
+ record = Rate.where(:rateable_id => self.id, :rateable_type => self.class.name, :rater_id => user_id, :dimension => dimension).first
64
+ record ? false : true
65
+ end
66
+
67
+ def rates(dimension=nil)
68
+ if dimension.nil?
69
+ self.send "rates_without_dimension"
70
+ else
71
+ self.send "#{dimension}_rates"
72
+ end
73
+ end
74
+
75
+
76
+ def update_permission
77
+ self.class.update_permission
78
+ end
79
+
80
+ module ClassMethods
81
+ def seems_rateable(opts={})
82
+ has_many :rates_without_dimension, :as => :rateable, :class_name => "Rate",
83
+ :dependent => :destroy, :conditions => {:dimension => nil}
84
+
85
+ has_many :raters_without_dimension, :through => :rates_without_dimension, :source => :rater
86
+
87
+ has_one :rate_average_without_dimension, :as => :cacheable, :class_name => "CachedRating",
88
+ :dependent => :destroy, :conditions => {:dimension => nil}
89
+
90
+ @allow = opts[:allow_update] ? true : false
91
+
92
+ def self.update_permission
93
+ @update_permission = @allow
94
+ end
95
+
96
+ if opts[:dimensions].is_a?(Array)
97
+ opts[:dimensions].each do |dimension|
98
+ has_many "#{dimension}_rates", :dependent => :destroy,
99
+ :conditions => {:dimension => dimension.to_s}, :class_name => "Rate", :as => :rateable
100
+ has_many "#{dimension}_raters", :through => "#{dimension}_rates", :source => :rater
101
+ has_one "#{dimension}_average", :as => :cacheable, :class_name => "CachedRating",
102
+ :dependent => :destroy, :conditions => {:dimension => dimension.to_s}
103
+ end
104
+ end
105
+ end
106
+
107
+ def seems_rateable_rater
108
+ has_many :ratings_given, :class_name => "Rate", :foreign_key => :rater_id
109
+ end
110
+
111
+ end
112
+ end
113
+
114
+
115
+ class ActiveRecord::Base
116
+ include SeemsRateable
117
+ end
@@ -0,0 +1,3 @@
1
+ module SeemsRateable
2
+ VERSION = "1.0.2"
3
+ end
@@ -0,0 +1,6 @@
1
+ require "seems_rateable/version"
2
+ require "seems_rateable/helpers"
3
+ require "seems_rateable/record"
4
+
5
+ module SeemsRateable
6
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'seems_rateable/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "seems_rateable"
8
+ gem.version = SeemsRateable::VERSION
9
+ gem.authors = ["Peter Toth"]
10
+ gem.email = ["proximin@gmail.com"]
11
+ gem.description = %q{Star rating gem for Rails application using jQuery plugin jRating}
12
+ gem.summary = %q{Star rating gem for Rails application using jQuery plugin jRating}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_runtime_dependency 'rails'
21
+
22
+ gem.add_development_dependency 'rake'
23
+ gem.add_development_dependency "rspec", "~> 2.6"
24
+
25
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: seems_rateable
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Peter Toth
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.6'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.6'
55
+ description: Star rating gem for Rails application using jQuery plugin jRating
56
+ email:
57
+ - proximin@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .project
64
+ - .rvmrc
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - lib/generators/seems_rateable/USAGE
70
+ - lib/generators/seems_rateable/seems_rateable_generator.rb
71
+ - lib/generators/seems_rateable/templates/cached_model.rb
72
+ - lib/generators/seems_rateable/templates/cached_rating_migration.rb
73
+ - lib/generators/seems_rateable/templates/controller.rb
74
+ - lib/generators/seems_rateable/templates/images/bg_jRatingInfos.png
75
+ - lib/generators/seems_rateable/templates/images/small.png
76
+ - lib/generators/seems_rateable/templates/images/stars.png
77
+ - lib/generators/seems_rateable/templates/javascripts/jRating.jquery.js.erb
78
+ - lib/generators/seems_rateable/templates/javascripts/rateable.jquery.js.erb
79
+ - lib/generators/seems_rateable/templates/model.rb
80
+ - lib/generators/seems_rateable/templates/rate_migration.rb
81
+ - lib/generators/seems_rateable/templates/stylesheets/jRating.jquery.css
82
+ - lib/seems_rateable.rb
83
+ - lib/seems_rateable/helpers.rb
84
+ - lib/seems_rateable/record.rb
85
+ - lib/seems_rateable/version.rb
86
+ - seems_rateable.gemspec
87
+ homepage: ''
88
+ licenses: []
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.0.3
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: Star rating gem for Rails application using jQuery plugin jRating
110
+ test_files: []