rateable_attributes 0.1.0
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/.gitignore +3 -0
- data/README.rdoc +52 -0
- data/Rakefile +19 -0
- data/VERSION +1 -0
- data/generators/USAGE +1 -0
- data/generators/rateable_attributes_generator.rb +13 -0
- data/generators/templates/migration.rb +17 -0
- data/generators/templates/rateable_attributes.js +24 -0
- data/generators/templates/rateable_attributes_helper.rb +31 -0
- data/generators/templates/star_hover.png +0 -0
- data/generators/templates/star_rated.png +0 -0
- data/generators/templates/star_unrated.png +0 -0
- data/init.rb +1 -0
- data/lib/rateable_attributes.rb +89 -0
- data/lib/rating.rb +6 -0
- data/rateable_attributes.gemspec +58 -0
- data/spec/make_rateable_spec.rb +163 -0
- data/spec/spec_helper.rb +36 -0
- metadata +73 -0
data/.gitignore
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
= RateableAttributes
|
2
|
+
|
3
|
+
RateableAttributes is a re-implementation of ActsAsRateable for multiple attribute support.
|
4
|
+
|
5
|
+
== Usage
|
6
|
+
|
7
|
+
=== Installation
|
8
|
+
|
9
|
+
To install as plugin:
|
10
|
+
|
11
|
+
script/plugin install git://github.com/sdepold/rateable_attributes.git
|
12
|
+
|
13
|
+
=== Preparation
|
14
|
+
|
15
|
+
In order to create the rating table just run the following commands:
|
16
|
+
|
17
|
+
script/generate rateable_attributes
|
18
|
+
rake db:migrate
|
19
|
+
|
20
|
+
This will generate a migration. Run rake db:migrate.
|
21
|
+
|
22
|
+
=== In the model
|
23
|
+
|
24
|
+
rateable_attributes :graphics, :sound, :whatever, :range => 1..5
|
25
|
+
|
26
|
+
This allows you to rate the model for the attributes graphics, sound and whatever.
|
27
|
+
To do so use
|
28
|
+
|
29
|
+
my_model.rate(3, a_user[, :the_attribute]) # you can just ignore the attribute to create a general rating
|
30
|
+
my_model.rate_graphics(3, a_user) # equals my_model.rate(3, a_user, :graphics)
|
31
|
+
|
32
|
+
=== Visualizing the average rating
|
33
|
+
|
34
|
+
RateableAttributes a method to the model called visualize_average_rating.
|
35
|
+
It can be called the following options:
|
36
|
+
|
37
|
+
- attribute = The attribute you want to display. Default: nil
|
38
|
+
- image_rated = The image/symbol you wish to be shown as reached rating. Default: A yellow star
|
39
|
+
- image_unrated = The image/symbol you wish to be shown as unreached rating. Default: A white star
|
40
|
+
- image_hover = The image/symbol you wish to be shown when hovering one of the rating images (see next option). Default: An orange star
|
41
|
+
- enable_rating = Should the user be able to click and rate?
|
42
|
+
- click_url = The URL which gets called, when a user clicked on a star to rate the model.
|
43
|
+
|
44
|
+
When you enable the rating option, the controller should return a json object as follows:
|
45
|
+
|
46
|
+
{new_rating: 2}
|
47
|
+
|
48
|
+
Important as well is, that you include the generated javascript file. Just do the following in your documents head:
|
49
|
+
|
50
|
+
= javascript_include_tag "rateable_attributes.js"
|
51
|
+
|
52
|
+
The javascript uses the prototype plugin. Feel free to change it for JQuery if you are using it.
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
begin
|
2
|
+
task :default => :spec
|
3
|
+
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
require 'jeweler'
|
6
|
+
|
7
|
+
Spec::Rake::SpecTask.new {|t| t.spec_opts = ['--color']}
|
8
|
+
Jeweler::Tasks.new do |gemspec|
|
9
|
+
gemspec.name = "rateable_attributes"
|
10
|
+
gemspec.summary = "Rate multiple attributes of models with Active Record."
|
11
|
+
gemspec.description = "Rate multiple attributes of models with Active Record."
|
12
|
+
gemspec.email = "dev@depold.com"
|
13
|
+
gemspec.homepage = "http://github.com/sdepold/rateable_attributes"
|
14
|
+
gemspec.authors = ["Sascha Depold"]
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
19
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/generators/USAGE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
blab
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class RateableAttributesGenerator < Rails::Generator::Base
|
2
|
+
def manifest
|
3
|
+
record do |m|
|
4
|
+
m.migration_template 'migration.rb', 'db/migrate', :migration_file_name => "rateable_attributes_migration"
|
5
|
+
m.directory "public/images/ratings"
|
6
|
+
m.file "star_rated.png", "public/images/ratings/star_rated.png"
|
7
|
+
m.file "star_unrated.png", "public/images/ratings/star_unrated.png"
|
8
|
+
m.file "star_hover.png", "public/images/ratings/star_hover.png"
|
9
|
+
m.file "rateable_attributes.js", "public/javascripts/rateable_attributes.js"
|
10
|
+
m.file "rateable_attributes_helper.rb", "app/helpers/rateable_attributes_helper.rb"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class RateableAttributesMigration < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :ratings do |t|
|
4
|
+
t.integer :user_id
|
5
|
+
t.integer :rateable_id
|
6
|
+
t.string :rateable_type
|
7
|
+
t.string :rateable_attribute
|
8
|
+
t.integer :rating
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
drop_table :ratings
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
function rateableAttributesHoverRatingImage(objectRating, idPrefix, hoveredRating, hoverImage) {
|
2
|
+
for(var i = 0; i <= hoveredRating; i++)
|
3
|
+
$(idPrefix + "_" + i).src = "/images/" + hoverImage;
|
4
|
+
}
|
5
|
+
|
6
|
+
function rateableAttributesUnhoverRatingImage(objectRating, maxRating, idPrefix, ratedImage, unratedImage) {
|
7
|
+
for(var i = 0; i < maxRating; i++) {
|
8
|
+
var imageURL = "/images/" + ((i < objectRating) ? ratedImage : unratedImage);
|
9
|
+
$(idPrefix + "_" + i).src = imageURL;
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
function rateableAttributesClickRatingImage(ajaxURL, clickedRating, clickedAttribute, maxRating, idPrefix, ratedImage, unratedImage) {
|
14
|
+
new Ajax.Request(ajaxURL, {
|
15
|
+
parameters: {
|
16
|
+
rating: clickedRating,
|
17
|
+
attribute: clickedAttribute
|
18
|
+
},
|
19
|
+
onSuccess:function(data) {
|
20
|
+
var result = data.responseJSON;
|
21
|
+
rateableAttributesUnhoverRatingImage(result.new_rating, maxRating, idPrefix, ratedImage, unratedImage);
|
22
|
+
}
|
23
|
+
});
|
24
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module RateableAttributesHelper
|
2
|
+
def visualize_average_rating(object, options={})
|
3
|
+
options[:attribute] ||= nil
|
4
|
+
options[:image_rated] ||= "ratings/star_rated.png"
|
5
|
+
options[:image_unrated] ||= "ratings/star_unrated.png"
|
6
|
+
options[:image_hover] ||= "ratings/star_hover.png"
|
7
|
+
options[:click_url] ||= ""
|
8
|
+
|
9
|
+
result = ""
|
10
|
+
rating = object.average_rating_rounded(options[:attribute])
|
11
|
+
max_rating = object.rateable_range.end
|
12
|
+
|
13
|
+
max_rating.times do |i|
|
14
|
+
id = "#{object.class.to_s.downcase}_#{options[:attribute] || "general"}_#{object.id}"
|
15
|
+
image_options = {:id => "#{id}_#{i}"}
|
16
|
+
image = ((i + 1) <= rating) ? options[:image_rated] : options[:image_unrated]
|
17
|
+
|
18
|
+
if options[:enable_rating]
|
19
|
+
image_options.merge!({
|
20
|
+
:onmousemove => "rateableAttributesHoverRatingImage(#{rating}, '#{id}', #{i}, '#{options[:image_hover]}')",
|
21
|
+
:onmouseout => "rateableAttributesUnhoverRatingImage(#{rating}, #{max_rating}, '#{id}', '#{options[:image_rated]}', '#{options[:image_unrated]}')",
|
22
|
+
:onclick => "rateableAttributesClickRatingImage('#{options[:click_url]}', #{i + 1}, '#{options[:attribute]}', #{max_rating}, '#{id}', '#{options[:image_rated]}', '#{options[:image_unrated]}')"
|
23
|
+
})
|
24
|
+
end
|
25
|
+
|
26
|
+
result << image_tag(image, image_options)
|
27
|
+
end
|
28
|
+
|
29
|
+
result
|
30
|
+
end
|
31
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "rateable_attributes"
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module RateableAttributes
|
2
|
+
def self.included(base)
|
3
|
+
base.extend ClassMethods
|
4
|
+
end
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def rateable_attributes(*args)
|
8
|
+
has_many :ratings, :as => :rateable
|
9
|
+
|
10
|
+
options = args.extract_options!
|
11
|
+
options[:range] ||= 1..5
|
12
|
+
|
13
|
+
{ :rateable_range => options[:range], :rateables => args }.each do |accessor, value|
|
14
|
+
next if respond_to?(accessor)
|
15
|
+
class_inheritable_accessor accessor
|
16
|
+
attr_protected accessor
|
17
|
+
self.send("#{accessor}=", value)
|
18
|
+
end
|
19
|
+
|
20
|
+
include RateableAttributes::ClassMethods
|
21
|
+
include RateableAttributes::InstanceMethods
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
end
|
27
|
+
|
28
|
+
module InstanceMethods
|
29
|
+
def is_valid_rateable_attribute?(attribute)
|
30
|
+
attribute.nil? || rateables.include?(attribute.to_sym)
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate_rating_data!(rating, attribute)
|
34
|
+
raise "#{attribute} is not valid for this model. Choose one of the following: #{rateables.join(', ')}" unless is_valid_rateable_attribute?(attribute)
|
35
|
+
raise "The rating #{rating} is not in allowed rating range: #{rateable_range.to_s}" unless rateable_range.include?(rating)
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
def rate(rating, user, attribute=nil)
|
40
|
+
validate_rating_data!(rating, attribute)
|
41
|
+
return rating_by(user, attribute) if was_rated_by?(user, attribute)
|
42
|
+
Rating.create({:user => user, :rating => rating, :rateable_attribute => attribute, :rateable => self})
|
43
|
+
end
|
44
|
+
|
45
|
+
def rate!(rating, user, attribute=nil)
|
46
|
+
validate_rating_data!(rating, attribute)
|
47
|
+
Rating.create!({:user => user, :rating => rating, :rateable_attribute => attribute, :rateable => self})
|
48
|
+
end
|
49
|
+
|
50
|
+
def average_rating(attribute=nil)
|
51
|
+
attribute = attribute.to_s unless attribute.nil?
|
52
|
+
all_ratings = ratings.find(:all, :conditions => {:rateable_attribute => attribute})
|
53
|
+
return 0.0 if all_ratings.empty?
|
54
|
+
all_ratings.sum(&:rating) / all_ratings.size
|
55
|
+
end
|
56
|
+
|
57
|
+
def average_rating_rounded(attribute=nil)
|
58
|
+
average_rating(attribute).round
|
59
|
+
end
|
60
|
+
|
61
|
+
def average_rating_percentage(attribute=nil)
|
62
|
+
average_rating(attribute) * 100 / rateable_range.end
|
63
|
+
end
|
64
|
+
|
65
|
+
def was_rated_by?(user, attribute=nil)
|
66
|
+
attribute = attribute.to_s unless attribute.nil?
|
67
|
+
ratings.find(:first, :conditions => {:user_id => user.id, :rateable_attribute => attribute}).present?
|
68
|
+
end
|
69
|
+
|
70
|
+
def rating_by(user, attribute=nil)
|
71
|
+
attribute = attribute.to_s unless attribute.nil?
|
72
|
+
ratings.find(:first, :conditions => {:user_id => user.id, :rateable_attribute => attribute})
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def method_missing(method, *args, &block)
|
78
|
+
return super(method, *args, &block) unless method.to_s.starts_with?("rate_")
|
79
|
+
|
80
|
+
# this will find method calls like rate_accuracy
|
81
|
+
attribute = method.to_s.split("rate_").last
|
82
|
+
rate(args[0], args[1], attribute) if rateables.include?(attribute.to_sym) && ![args[0], args[1]].include?(nil)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class ActiveRecord::Base
|
88
|
+
include RateableAttributes
|
89
|
+
end
|
data/lib/rating.rb
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
class Rating < ActiveRecord::Base
|
2
|
+
belongs_to :user
|
3
|
+
validates_presence_of :rateable_id, :rateable_type, :user_id, :rating
|
4
|
+
validates_uniqueness_of :rateable_id, :scope => [:rateable_type, :user_id, :rateable_attribute]
|
5
|
+
belongs_to :rateable, :polymorphic => true
|
6
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{rateable_attributes}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Sascha Depold"]
|
12
|
+
s.date = %q{2010-02-28}
|
13
|
+
s.description = %q{Rate multiple attributes of models with Active Record.}
|
14
|
+
s.email = %q{dev@depold.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"README.rdoc",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"generators/USAGE",
|
24
|
+
"generators/rateable_attributes_generator.rb",
|
25
|
+
"generators/templates/migration.rb",
|
26
|
+
"generators/templates/rateable_attributes.js",
|
27
|
+
"generators/templates/rateable_attributes_helper.rb",
|
28
|
+
"generators/templates/star_hover.png",
|
29
|
+
"generators/templates/star_rated.png",
|
30
|
+
"generators/templates/star_unrated.png",
|
31
|
+
"init.rb",
|
32
|
+
"lib/rateable_attributes.rb",
|
33
|
+
"lib/rating.rb",
|
34
|
+
"rateable_attributes.gemspec",
|
35
|
+
"spec/make_rateable_spec.rb",
|
36
|
+
"spec/spec_helper.rb"
|
37
|
+
]
|
38
|
+
s.homepage = %q{http://github.com/sdepold/rateable_attributes}
|
39
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
40
|
+
s.require_paths = ["lib"]
|
41
|
+
s.rubygems_version = %q{1.3.5}
|
42
|
+
s.summary = %q{Rate multiple attributes of models with Active Record.}
|
43
|
+
s.test_files = [
|
44
|
+
"spec/make_rateable_spec.rb",
|
45
|
+
"spec/spec_helper.rb"
|
46
|
+
]
|
47
|
+
|
48
|
+
if s.respond_to? :specification_version then
|
49
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
50
|
+
s.specification_version = 3
|
51
|
+
|
52
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
53
|
+
else
|
54
|
+
end
|
55
|
+
else
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/spec_helper'
|
2
|
+
|
3
|
+
describe Project do
|
4
|
+
describe :rateable_range do
|
5
|
+
it "should have a range" do
|
6
|
+
Project.rateable_range.should_not be_nil
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have the attributes, specified in model" do
|
10
|
+
Project.rateables.should == [:usability, :performance, :functionality]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe :is_valid_rateable_attribute? do
|
15
|
+
before :all do
|
16
|
+
@project = Project.create(:name => "foo")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should return true if passed value is nil (= general rating)" do
|
20
|
+
@project.is_valid_rateable_attribute?(nil).should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return true if passed value is one of the specified attributes" do
|
24
|
+
@project.is_valid_rateable_attribute?(:usability).should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return false if passed value is not nil and not one of the specified attributes" do
|
28
|
+
@project.is_valid_rateable_attribute?(:bar).should be_false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe :validate_rating_data! do
|
33
|
+
before :all do
|
34
|
+
@project = Project.create(:name => "foo")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should throw an exception if is_valid_rateable_attribute? returns false" do
|
38
|
+
lambda{@project.validate_rating_data!(9, :foo)}.should raise_error
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should throw an exception if rating is not in rateable_range" do
|
42
|
+
lambda{@project.validate_rating_data!(8, nil)}.should raise_error
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return true if everything is nice" do
|
46
|
+
@project.validate_rating_data!(3, nil).should be_true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe :rate do
|
51
|
+
before :each do
|
52
|
+
@project = Project.create(:name => "foo")
|
53
|
+
@project.should_receive(:validate_rating_data!).and_return true
|
54
|
+
@user = User.create(:name => "max")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return available rating if already rated by user" do
|
58
|
+
@project.should_receive(:was_rated_by?).and_return true
|
59
|
+
@project.should_receive(:rating_by)
|
60
|
+
lambda{@project.rate(1, @user)}.should_not change(Rating, :count).by(1)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should not return a given rating but create one if not yet rated by user" do
|
64
|
+
@project.should_receive(:was_rated_by?).and_return false
|
65
|
+
@project.should_not_receive(:rating_by)
|
66
|
+
lambda{@project.rate(1, @user)}.should change(Rating, :count).by(1)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe :average_rating do
|
71
|
+
before :each do
|
72
|
+
Rating.destroy_all
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should return 0.0 if no rating is given" do
|
76
|
+
Project.create(:name => "foo").average_rating.should == 0.0
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should calculate correctly" do
|
80
|
+
p = Project.create(:name => "foo")
|
81
|
+
u = User.create(:name => "max")
|
82
|
+
u2 = User.create(:name => "maxine")
|
83
|
+
|
84
|
+
p.rate 1, u
|
85
|
+
p.rate 5, u2
|
86
|
+
|
87
|
+
p.average_rating.should == 3.0
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe :average_rating_rounded do
|
92
|
+
it "should return rounded ratings" do
|
93
|
+
Rating.destroy_all
|
94
|
+
|
95
|
+
p = Project.create(:name => "foo")
|
96
|
+
u = User.create(:name => "max")
|
97
|
+
u2 = User.create(:name => "maxine")
|
98
|
+
|
99
|
+
p.rate 1, u
|
100
|
+
p.rate 2, u2
|
101
|
+
|
102
|
+
p.average_rating_rounded.should == 1
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe :average_rating_percentage do
|
107
|
+
it "should return a percentage" do
|
108
|
+
p = Project.create(:name => "foo")
|
109
|
+
p.rate 4, User.create(:name => "max")
|
110
|
+
|
111
|
+
p.average_rating_percentage.should == 80
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe :was_rated_by? do
|
116
|
+
before :each do
|
117
|
+
@project = Project.create(:name => "hello world")
|
118
|
+
@user = User.create(:name => "my_user")
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should return false if user hasn't rated yet" do
|
122
|
+
@project.was_rated_by?(@user).should be_false
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should return true if user has already rated" do
|
126
|
+
@project.rate 1, @user
|
127
|
+
@project.was_rated_by?(@user).should be_true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe :rating_by do
|
132
|
+
before :each do
|
133
|
+
@project = Project.create(:name => "hello world")
|
134
|
+
@user = User.create(:name => "my_user")
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should return nil if no rating was given" do
|
138
|
+
@project.rating_by(@user).should be_nil
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should return the rating object if rating was given" do
|
142
|
+
@project.rate 1, @user
|
143
|
+
r = @project.rating_by(@user)
|
144
|
+
r.should_not be_nil
|
145
|
+
r.class.to_s.should == "Rating"
|
146
|
+
r.rating.should == 1
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe :method_missing do
|
151
|
+
before :each do
|
152
|
+
@project = Project.create(:name => "hello world")
|
153
|
+
@user = User.create(:name => "my_user")
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
it "should add methods for rating the defined attributes" do
|
158
|
+
lambda{@project.rate_usability(1, @user)}.should change(Rating, :count).by(1)
|
159
|
+
lambda{@project.rate_performance(1, @user)}.should change(Rating, :count).by(1)
|
160
|
+
lambda{@project.rate_functionality(1, @user)}.should change(Rating, :count).by(1)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require "active_record"
|
3
|
+
require "action_view"
|
4
|
+
require File.dirname(__FILE__)+"/../lib/rateable_attributes.rb"
|
5
|
+
require File.dirname(__FILE__)+"/../generators/templates/migration.rb"
|
6
|
+
require File.dirname(__FILE__)+"/../lib/rating.rb"
|
7
|
+
|
8
|
+
|
9
|
+
ActiveRecord::Base.establish_connection({
|
10
|
+
:adapter => "sqlite3",
|
11
|
+
:database => ":memory:"
|
12
|
+
})
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define(:version => 1) do
|
15
|
+
RateableAttributesMigration.up
|
16
|
+
|
17
|
+
create_table :projects, :force=>true do |t|
|
18
|
+
t.string :name
|
19
|
+
t.timestamps
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table :users, :force => true do |t|
|
23
|
+
t.string :name
|
24
|
+
t.timestamps
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Project < ActiveRecord::Base
|
29
|
+
rateable_attributes :usability, :performance, :functionality
|
30
|
+
validates_presence_of :name
|
31
|
+
end
|
32
|
+
|
33
|
+
class User < ActiveRecord::Base
|
34
|
+
validates_presence_of :name
|
35
|
+
has_many :ratings
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rateable_attributes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sascha Depold
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-02-28 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Rate multiple attributes of models with Active Record.
|
17
|
+
email: dev@depold.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- .gitignore
|
26
|
+
- README.rdoc
|
27
|
+
- Rakefile
|
28
|
+
- VERSION
|
29
|
+
- generators/USAGE
|
30
|
+
- generators/rateable_attributes_generator.rb
|
31
|
+
- generators/templates/migration.rb
|
32
|
+
- generators/templates/rateable_attributes.js
|
33
|
+
- generators/templates/rateable_attributes_helper.rb
|
34
|
+
- generators/templates/star_hover.png
|
35
|
+
- generators/templates/star_rated.png
|
36
|
+
- generators/templates/star_unrated.png
|
37
|
+
- init.rb
|
38
|
+
- lib/rateable_attributes.rb
|
39
|
+
- lib/rating.rb
|
40
|
+
- rateable_attributes.gemspec
|
41
|
+
- spec/make_rateable_spec.rb
|
42
|
+
- spec/spec_helper.rb
|
43
|
+
has_rdoc: true
|
44
|
+
homepage: http://github.com/sdepold/rateable_attributes
|
45
|
+
licenses: []
|
46
|
+
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options:
|
49
|
+
- --charset=UTF-8
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.3.5
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: Rate multiple attributes of models with Active Record.
|
71
|
+
test_files:
|
72
|
+
- spec/make_rateable_spec.rb
|
73
|
+
- spec/spec_helper.rb
|