acts_as_votable 0.5.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dbab821eaed3208a063e8bcd39f67a4e28fb79b0
4
+ data.tar.gz: d788852ccc01167a02a0b5a8d09b76d4cb13b212
5
+ SHA512:
6
+ metadata.gz: d8323034cb58bd685120c2ef882ffe06f0a94c5c7d503207d83e4bcac52d9d8e83d8aedd3d04c230225ca1a6f2816a6e2a298271032afb65584cac79df2a02f1
7
+ data.tar.gz: 252fe90880661cefb906365409fd77da3853cafb3ca71633187ffe64ecdf17dee9abfa8ba06ac6f70841cfd7b402dcb700cc7beec87eb9d3492360fba5de31fd
data/.gitignore CHANGED
@@ -2,4 +2,5 @@ pkg/*
2
2
  *.gem
3
3
  .bundle
4
4
  nbproject/*
5
+ Gemfile.lock
5
6
  bin
data/.travis.yml ADDED
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - 2.0.0
7
+ env:
8
+ - "RAILS_VERSION=3.0.0"
9
+ - "RAILS_VERSION=3.1.0"
10
+ - "RAILS_VERSION=3.2.0"
11
+ - "RAILS_VERSION=4.0.0"
12
+ matrix:
13
+ exclude:
14
+ - rvm: 1.8.7
15
+ env: "RAILS_VERSION=4.0.0"
16
+ - rvm: 1.9.2
17
+ env: "RAILS_VERSION=4.0.0"
data/Gemfile CHANGED
@@ -1,4 +1,17 @@
1
- source "http://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in acts_as_votable.gemspec
4
4
  gemspec
5
+
6
+ rails_version = ENV['RAILS_VERSION'] || 'default'
7
+
8
+ rails = case rails_version
9
+ when 'master'
10
+ { :github => 'rails/rails'}
11
+ when 'default'
12
+ '~> 3.2.0'
13
+ else
14
+ "~> #{rails_version}"
15
+ end
16
+
17
+ gem 'rails', rails
data/README.markdown CHANGED
@@ -1,5 +1,7 @@
1
1
  # Acts As Votable (aka Acts As Likeable)
2
2
 
3
+ [![Build Status](https://travis-ci.org/ryanto/acts_as_votable.png)](https://travis-ci.org/ryanto/acts_as_votable)
4
+
3
5
  Acts As Votable is a Ruby Gem specifically written for Rails/ActiveRecord models.
4
6
  The main goals of this gem are:
5
7
 
@@ -11,11 +13,13 @@ The main goals of this gem are:
11
13
 
12
14
  ## Installation
13
15
 
14
- ### Rails 3+
16
+ ### Rails 3.0, 3.1, 3.2, and 4.0+
15
17
 
16
18
  Just add the following to your Gemfile.
17
19
 
18
- gem 'acts_as_votable', '~> 0.5.0'
20
+ ```ruby
21
+ gem 'acts_as_votable', '~> 0.7.1'
22
+ ```
19
23
 
20
24
  And follow that up with a ``bundle install``.
21
25
 
@@ -35,81 +39,92 @@ caching section of this document for more information.
35
39
 
36
40
  ### Votable Models
37
41
 
38
- class Post < ActiveRecord::Base
39
- acts_as_votable
40
- end
42
+ ```ruby
43
+ class Post < ActiveRecord::Base
44
+ acts_as_votable
45
+ end
41
46
 
42
- @post = Post.new(:name => 'my post!')
43
- @post.save
47
+ @post = Post.new(:name => 'my post!')
48
+ @post.save
44
49
 
45
- @post.liked_by @user
46
- @post.votes.size # => 1
50
+ @post.liked_by @user
51
+ @post.votes.size # => 1
52
+ ```
47
53
 
48
54
  ### Like/Dislike Yes/No Up/Down
49
55
 
50
56
  Here are some voting examples. All of these calls are valid and acceptable. The
51
57
  more natural calls are the first few examples.
52
58
 
53
- @post.liked_by @user1
54
- @post.downvote_from @user2
55
- @post.vote :voter => @user3
56
- @post.vote :voter => @user4, :vote => 'bad'
57
- @post.vote :voter => @user5, :vote => 'like'
58
-
59
+ ```ruby
60
+ @post.liked_by @user1
61
+ @post.downvote_from @user2
62
+ @post.vote :voter => @user3
63
+ @post.vote :voter => @user4, :vote => 'bad'
64
+ @post.vote :voter => @user5, :vote => 'like'
65
+ ```
59
66
 
60
- By default all votes are positive, so @user3 has cast a 'good' vote for @post.
67
+ By default all votes are positive, so `@user3` has cast a 'good' vote for `@post`.
61
68
 
62
- @user1, @user3, and @user5 all voted in favor of @post.
69
+ `@user1`, `@user3`, and `@user5` all voted in favor of `@post`.
63
70
 
64
- @user2 and @user4 on the other had has voted against @post.
71
+ `@user2` and `@user4` on the other had has voted against `@post`.
65
72
 
66
73
 
67
74
  Just about any word works for casting a vote in favor or against post. Up/Down,
68
- Like/Dislike, Positive/Negative... the list goes on-and-on. Boolean flags ``true`` and
69
- ``false`` are also applicable.
75
+ Like/Dislike, Positive/Negative... the list goes on-and-on. Boolean flags `true` and
76
+ `false` are also applicable.
70
77
 
71
78
  Revisiting the previous example of code.
72
79
 
73
- # positive votes
74
- @post.liked_by @user1
75
- @post.vote :voter => @user3
76
- @post.vote :voter => @user5, :vote => 'like'
80
+ ```ruby
81
+ # positive votes
82
+ @post.liked_by @user1
83
+ @post.vote :voter => @user3
84
+ @post.vote :voter => @user5, :vote => 'like'
77
85
 
78
- # negative votes
79
- @post.downvote_from @user2
80
- @post.vote :voter => @user2, :vote => 'bad'
86
+ # negative votes
87
+ @post.downvote_from @user2
88
+ @post.vote :voter => @user2, :vote => 'bad'
81
89
 
82
- # tally them up!
83
- @post.votes.size # => 5
84
- @post.likes.size # => 3
85
- @post.upvotes.size # => 3
86
- @post.dislikes.size # => 2
87
- @post.downvotes.size # => 2
90
+ # tally them up!
91
+ @post.votes.size # => 5
92
+ @post.likes.size # => 3
93
+ @post.upvotes.size # => 3
94
+ @post.dislikes.size # => 2
95
+ @post.downvotes.size # => 2
96
+ ```
88
97
 
89
98
  Active Record scopes are provided to make life easier.
90
99
 
91
- @post.votes.up.by_type(User)
92
- @post.votes.down
93
- @user1.votes.up
94
- @user1.votes.down
95
- @user1.votes.up.by_type(Post)
100
+ ```ruby
101
+ @post.votes.up.by_type(User)
102
+ @post.votes.down
103
+ @user1.votes.up
104
+ @user1.votes.down
105
+ @user1.votes.up.by_type(Post)
106
+ ```
96
107
 
97
108
  Once scoping is complete, you can also trigger a get for the
98
109
  voter/votable
99
110
 
100
- @post.votes.up.by_type(User).voters
101
- @post.votes.down.by_type(User).voters
111
+ ```ruby
112
+ @post.votes.up.by_type(User).voters
113
+ @post.votes.down.by_type(User).voters
102
114
 
103
- @user.votes.up.for_type(Post).votables
104
- @user.votes.up.votables
115
+ @user.votes.up.for_type(Post).votables
116
+ @user.votes.up.votables
117
+ ```
105
118
 
106
119
  You can also 'unvote' a model to remove a previous vote.
107
120
 
108
- @post.liked_by @user1
109
- @post.unliked_by @user1
121
+ ```ruby
122
+ @post.liked_by @user1
123
+ @post.unliked_by @user1
110
124
 
111
- @post.disliked_by @user1
112
- @post.undisliked_by @user1
125
+ @post.disliked_by @user1
126
+ @post.undisliked_by @user1
127
+ ```
113
128
 
114
129
  Unvoting works for both positive and negative votes.
115
130
 
@@ -117,124 +132,168 @@ Unvoting works for both positive and negative votes.
117
132
 
118
133
  You can add an scope to your vote
119
134
 
120
- # positive votes
121
- @post.liked_by @user1, :vote_scope => 'rank'
122
- @post.vote :voter => @user3, :vote_scope => 'rank'
123
- @post.vote :voter => @user5, :vote => 'like', :vote_scope => 'rank'
124
-
125
- # negative votes
126
- @post.downvote_from @user2, :vote_scope => 'rank'
127
- @post.vote :voter => @user2, :vote => 'bad', :vote_scope => 'rank'
128
-
129
- # tally them up!
130
- @post.find_votes(:vote_scope => 'rank').size # => 5
131
- @post.likes(:vote_scope => 'rank').size # => 3
132
- @post.upvotes(:vote_scope => 'rank').size # => 3
133
- @post.dislikes(:vote_scope => 'rank').size # => 2
134
- @post.downvotes(:vote_scope => 'rank').size # => 2
135
-
136
- # votable model can be voted under different scopes
137
- # by the same user
138
- @post.vote :voter => @user1, :vote_scope => 'week'
139
- @post.vote :voter => @user1, :vote_scope => 'month'
140
-
141
- @post.votes.size # => 2
142
- @post.find_votes(:vote_scope => 'week').size # => 1
143
- @post.find_votes(:vote_scope => 'month').size # => 1
135
+ ```ruby
136
+ # positive votes
137
+ @post.liked_by @user1, :vote_scope => 'rank'
138
+ @post.vote :voter => @user3, :vote_scope => 'rank'
139
+ @post.vote :voter => @user5, :vote => 'like', :vote_scope => 'rank'
140
+
141
+ # negative votes
142
+ @post.downvote_from @user2, :vote_scope => 'rank'
143
+ @post.vote :voter => @user2, :vote => 'bad', :vote_scope => 'rank'
144
+
145
+ # tally them up!
146
+ @post.find_votes(:vote_scope => 'rank').size # => 5
147
+ @post.likes(:vote_scope => 'rank').size # => 3
148
+ @post.upvotes(:vote_scope => 'rank').size # => 3
149
+ @post.dislikes(:vote_scope => 'rank').size # => 2
150
+ @post.downvotes(:vote_scope => 'rank').size # => 2
151
+
152
+ # votable model can be voted under different scopes
153
+ # by the same user
154
+ @post.vote :voter => @user1, :vote_scope => 'week'
155
+ @post.vote :voter => @user1, :vote_scope => 'month'
156
+
157
+ @post.votes.size # => 2
158
+ @post.find_votes(:vote_scope => 'week').size # => 1
159
+ @post.find_votes(:vote_scope => 'month').size # => 1
160
+ ```
161
+ ### Adding weights to your votes
162
+
163
+ You can add weight to your vote. The default value is 1.
164
+
165
+ ```ruby
166
+ # positive votes
167
+ @post.liked_by @user1, :vote_weight => 1
168
+ @post.vote :voter => @user3, :vote_weight => 2
169
+ @post.vote :voter => @user5, :vote => 'like', :vote_scope => 'rank', :vote_weight => 3
170
+
171
+ # negative votes
172
+ @post.downvote_from @user2, :vote_scope => 'rank', :vote_weight => 1
173
+ @post.vote :voter => @user2, :vote => 'bad', :vote_scope => 'rank', :vote_weight => 3
174
+
175
+ # tally them up!
176
+ @post.find_votes(:vote_scope => 'rank').sum(:vote_weight) # => 6
177
+ @post.likes(:vote_scope => 'rank').sum(:vote_weight) # => 6
178
+ @post.upvotes(:vote_scope => 'rank').sum(:vote_weight) # => 6
179
+ @post.dislikes(:vote_scope => 'rank').sum(:vote_weight) # => 4
180
+ @post.downvotes(:vote_scope => 'rank').sum(:vote_weight) # => 4
181
+ ```
144
182
 
145
183
  ### The Voter
146
184
 
147
- You can have your voters ``acts_as_voter`` to provide some reserve functionality.
185
+ You can have your voters `acts_as_voter` to provide some reserve functionality.
148
186
 
149
- class User < ActiveRecord::Base
150
- acts_as_voter
151
- end
187
+ ```ruby
188
+ class User < ActiveRecord::Base
189
+ acts_as_voter
190
+ end
152
191
 
153
- @user.likes @article
192
+ @user.likes @article
154
193
 
155
- @article.votes.size # => 1
156
- @article.likes.size # => 1
157
- @article.dislikes.size # => 0
194
+ @article.votes.size # => 1
195
+ @article.likes.size # => 1
196
+ @article.dislikes.size # => 0
197
+ ```
158
198
 
159
199
  To check if a voter has voted on a model, you can use ``voted_for?``. You can
160
200
  check how the voter voted by using ``voted_as_when_voted_for``.
161
201
 
162
- @user.likes @comment1
163
- @user.up_votes @comment2
164
- # user has not voted on @comment3
202
+ ```ruby
203
+ @user.likes @comment1
204
+ @user.up_votes @comment2
205
+ # user has not voted on @comment3
165
206
 
166
- @user.voted_for? @comment1 # => true
167
- @user.voted_for? @comment2 # => true
168
- @user.voted_for? @comment3 # => false
207
+ @user.voted_for? @comment1 # => true
208
+ @user.voted_for? @comment2 # => true
209
+ @user.voted_for? @comment3 # => false
169
210
 
170
- @user.voted_as_when_voted_for @comment1 # => true, he liked it
171
- @user.voted_as_when_voted_for @comment2 # => false, he didnt like it
172
- @user.voted_as_when_voted_for @comment3 # => nil, he has yet to vote
211
+ @user.voted_as_when_voted_for @comment1 # => true, he liked it
212
+ @user.voted_as_when_voted_for @comment2 # => false, he didnt like it
213
+ @user.voted_as_when_voted_for @comment3 # => nil, he has yet to vote
214
+ ```
173
215
 
174
216
  You can also check whether the voter has voted up or down.
175
217
 
176
- @user.likes @comment1
177
- @user.dislikes @comment2
178
- # user has not voted on @comment3
218
+ ```ruby
219
+ @user.likes @comment1
220
+ @user.dislikes @comment2
221
+ # user has not voted on @comment3
179
222
 
180
- @user.voted_up_on? @comment1 # => true
181
- @user.voted_down_on? @comment1 # => false
223
+ @user.voted_up_on? @comment1 # => true
224
+ @user.voted_down_on? @comment1 # => false
182
225
 
183
- @user.voted_down_on? @comment2 # => true
184
- @user.voted_up_on? @comment2 # => false
226
+ @user.voted_down_on? @comment2 # => true
227
+ @user.voted_up_on? @comment2 # => false
185
228
 
186
- @user.voted_up_on? @comment3 # => false
187
- @user.voted_down_on? @comment3 # => false
229
+ @user.voted_up_on? @comment3 # => false
230
+ @user.voted_down_on? @comment3 # => false
231
+ ```
188
232
 
189
- Aliases for methods ``voted_up_on?`` and ``voted_down_on?`` are: ``voted_up_for?``, ``voted_down_for?``, ``liked?`` and ``disliked?``.
233
+ Aliases for methods `voted_up_on?` and `voted_down_on?` are: `voted_up_for?`, `voted_down_for?`, `liked?` and `disliked?`.
190
234
 
191
235
  Also, you can obtain a list of all the objects a user has voted for.
192
236
  This returns the actual objects instead of instances of the Vote model.
193
237
  All objects are eager loaded
194
238
 
195
- @user.find_voted_items
239
+ ```ruby
240
+ @user.find_voted_items
196
241
 
197
- @user.find_up_voted_items
198
- @user.find_liked_items
242
+ @user.find_up_voted_items
243
+ @user.find_liked_items
199
244
 
200
- @user.find_down_voted_items
201
- @user.find_disliked_items
245
+ @user.find_down_voted_items
246
+ @user.find_disliked_items
247
+ ```
202
248
 
203
249
  Members of an individual model that a user has voted for can also be
204
250
  displayed. The result is an ActiveRecord Relation.
205
251
 
206
- @user.get_voted Comment
252
+ ```ruby
253
+ @user.get_voted Comment
207
254
 
208
- @user.get_up_voted Comment
255
+ @user.get_up_voted Comment
209
256
 
210
- @user.get_down_voted Comment
257
+ @user.get_down_voted Comment
258
+ ```
211
259
 
212
260
  ### Registered Votes
213
261
 
214
262
  Voters can only vote once per model. In this example the 2nd vote does not count
215
- because @user has already voted for @shoe.
263
+ because `@user` has already voted for `@shoe`.
216
264
 
217
- @user.likes @shoe
218
- @user.likes @shoe
265
+ ```ruby
266
+ @user.likes @shoe
267
+ @user.likes @shoe
219
268
 
220
- @shoe.votes # => 1
221
- @shoe.likes # => 1
269
+ @shoe.votes # => 1
270
+ @shoe.likes # => 1
271
+ ```
222
272
 
223
- To check if a vote counted, or registered, use vote_registered? on your model
273
+ To check if a vote counted, or registered, use `vote_registered?` on your model
224
274
  after voting. For example:
225
275
 
226
- @hat.liked_by @user
227
- @hat.vote_registered? # => true
276
+ ```ruby
277
+ @hat.liked_by @user
278
+ @hat.vote_registered? # => true
228
279
 
229
- @hat.liked_by => @user
230
- @hat.vote_registered? # => false, because @user has already voted this way
280
+ @hat.liked_by => @user
281
+ @hat.vote_registered? # => false, because @user has already voted this way
231
282
 
232
- @hat.disliked_by @user
233
- @hat.vote_registered? # => true, because user changed their vote
283
+ @hat.disliked_by @user
284
+ @hat.vote_registered? # => true, because user changed their vote
234
285
 
235
- @hat.votes.size # => 1
236
- @hat.positives.size # => 0
237
- @hat.negatives.size # => 1
286
+ @hat.votes.size # => 1
287
+ @hat.positives.size # => 0
288
+ @hat.negatives.size # => 1
289
+ ```
290
+
291
+ To permit duplicates entries of a same voter, use option duplicate. Also notice that this
292
+ will limit some other methods that didn't deal with multiples votes, in this case, the last vote will be considered.
293
+
294
+ ```ruby
295
+ @hat.vote voter: @user, :duplicate => true
296
+ ```
238
297
 
239
298
  ## Caching
240
299
 
@@ -242,37 +301,55 @@ To speed up perform you can add cache columns to your votable model's table. Th
242
301
  columns will automatically be updated after each vote. For example, if we wanted
243
302
  to speed up @post we would use the following migration:
244
303
 
245
- class AddCachedVotesToPosts < ActiveRecord::Migration
246
- def self.up
247
- add_column :posts, :cached_votes_total, :integer, :default => 0
248
- add_column :posts, :cached_votes_score, :integer, :default => 0
249
- add_column :posts, :cached_votes_up, :integer, :default => 0
250
- add_column :posts, :cached_votes_down, :integer, :default => 0
251
- add_index :posts, :cached_votes_total
252
- add_index :posts, :cached_votes_score
253
- add_index :posts, :cached_votes_up
254
- add_index :posts, :cached_votes_down
255
- end
256
-
257
- def self.down
258
- remove_column :posts, :cached_votes_total
259
- remove_column :posts, :cached_votes_score
260
- remove_column :posts, :cached_votes_up
261
- remove_column :posts, :cached_votes_down
262
- end
263
- end
304
+ ```ruby
305
+ class AddCachedVotesToPosts < ActiveRecord::Migration
306
+ def self.up
307
+ add_column :posts, :cached_votes_total, :integer, :default => 0
308
+ add_column :posts, :cached_votes_score, :integer, :default => 0
309
+ add_column :posts, :cached_votes_up, :integer, :default => 0
310
+ add_column :posts, :cached_votes_down, :integer, :default => 0
311
+ add_column :posts, :cached_weighted_score, :integer, :default => 0
312
+ add_index :posts, :cached_votes_total
313
+ add_index :posts, :cached_votes_score
314
+ add_index :posts, :cached_votes_up
315
+ add_index :posts, :cached_votes_down
316
+ add_index :posts, :cached_weighted_score
317
+
318
+ # Uncomment this line to force caching of existing votes
319
+ # Post.find_each(&:update_cached_votes)
320
+ end
321
+
322
+ def self.down
323
+ remove_column :posts, :cached_votes_total
324
+ remove_column :posts, :cached_votes_score
325
+ remove_column :posts, :cached_votes_up
326
+ remove_column :posts, :cached_votes_down
327
+ remove_column :posts, :cached_weighted_score
328
+ end
329
+ end
330
+ ```
264
331
 
265
332
  ## Testing
266
333
 
267
- All tests follow the RSpec format and are located in the spec directory
334
+ All tests follow the RSpec format and are located in the spec directory.
335
+ They can be run with:
336
+
337
+ ```
338
+ rake spec
339
+ ```
340
+
341
+ ## License
342
+
343
+ Acts as votable is released under the [MIT
344
+ License](http://www.opensource.org/licenses/MIT).
268
345
 
269
346
  ## TODO
270
347
 
271
348
  - Pass in a block of options when creating acts_as. Allow for things
272
349
  like disabling the aliasing
273
350
 
274
- - Smarter language syntax. Example: ``@user.likes`` will return all of the votables
275
- that the user likes, while ``@user.likes @model`` will cast a vote for @model by
351
+ - Smarter language syntax. Example: `@user.likes` will return all of the votables
352
+ that the user likes, while `@user.likes @model` will cast a vote for @model by
276
353
  @user.
277
354
 
278
355
  - Need to test a model that is votable as well as a voter
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc "Run specs"
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ desc 'Default: run specs.'
10
+ task :default => :spec
@@ -19,11 +19,6 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
21
 
22
-
23
-
24
22
  s.add_development_dependency "rspec"
25
- s.add_development_dependency "sqlite3"
26
-
27
- s.add_dependency "rails", '>=3.0.0'
28
-
23
+ s.add_development_dependency "sqlite3", '1.3.7'
29
24
  end
@@ -0,0 +1,19 @@
1
+ module ActsAsVotable
2
+ module Extenders
3
+
4
+ module Controller
5
+
6
+ def voter_params(params_object = params[:vote])
7
+ params_object.permit(:votable_id, :votable_type,
8
+ :voter_id, :voter_type,
9
+ :votable, :voter,
10
+ :vote_flag, :vote_scope)
11
+ end
12
+
13
+ def votable_params(params_object = params[:vote])
14
+ params_object.permit(:vote_registered)
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
1
  module ActsAsVotable
2
- VERSION = "0.5.0"
2
+ VERSION = "0.8.0"
3
3
  end