seems_rateable 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/.project +18 -0
- data/.rvmrc +0 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +7 -0
- data/lib/generators/seems_rateable/USAGE +0 -0
- data/lib/generators/seems_rateable/seems_rateable_generator.rb +65 -0
- data/lib/generators/seems_rateable/templates/cached_model.rb +4 -0
- data/lib/generators/seems_rateable/templates/cached_rating_migration.rb +17 -0
- data/lib/generators/seems_rateable/templates/controller.rb +15 -0
- data/lib/generators/seems_rateable/templates/images/bg_jRatingInfos.png +0 -0
- data/lib/generators/seems_rateable/templates/images/small.png +0 -0
- data/lib/generators/seems_rateable/templates/images/stars.png +0 -0
- data/lib/generators/seems_rateable/templates/javascripts/jRating.jquery.js.erb +225 -0
- data/lib/generators/seems_rateable/templates/javascripts/rateable.jquery.js.erb +24 -0
- data/lib/generators/seems_rateable/templates/model.rb +7 -0
- data/lib/generators/seems_rateable/templates/rate_migration.rb +21 -0
- data/lib/generators/seems_rateable/templates/stylesheets/jRating.jquery.css +48 -0
- data/lib/seems_rateable/helpers.rb +22 -0
- data/lib/seems_rateable/record.rb +117 -0
- data/lib/seems_rateable/version.rb +3 -0
- data/lib/seems_rateable.rb +6 -0
- data/seems_rateable.gemspec +25 -0
- metadata +110 -0
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
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
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
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,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
|
Binary file
|
Binary file
|
Binary file
|
@@ -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,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,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: []
|