acts_as_votable 0.5.0 → 0.7.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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +17 -0
- data/Gemfile +14 -1
- data/README.markdown +185 -142
- data/Rakefile +8 -0
- data/acts_as_votable.gemspec +1 -6
- data/lib/acts_as_votable/extenders/controller.rb +19 -0
- data/lib/acts_as_votable/version.rb +1 -1
- data/lib/acts_as_votable/votable.rb +11 -3
- data/lib/acts_as_votable/vote.rb +8 -6
- data/lib/acts_as_votable/voter.rb +8 -8
- data/lib/acts_as_votable.rb +5 -0
- data/lib/generators/acts_as_votable/migration/templates/active_record/migration.rb +5 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/votable_spec.rb +6 -0
- data/spec/voter_spec.rb +6 -0
- metadata +15 -42
- data/Gemfile.lock +0 -104
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 761f4de1f6cb69440c40761f9a73bf33ebd0d626
|
|
4
|
+
data.tar.gz: 531c9e70b810c33a8855021f05e1cbf6a2fe6053
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: bf5fc76011445515ae9ad68617af57c24ba660e1c8341fb360ee2874b4966ca644c3c9d337d0726b6fb29c59a8a6bb1f68b591975417245f10a2e683df05ff91
|
|
7
|
+
data.tar.gz: 2113bdcec62e87a3fb88bc97bd3b7b3bd1cf67d098b0502b26c41590cdf8ea1f2e1780cd5c63d14c75084422d2039f947cc09761ff4e405e423d035f57054c79
|
data/.gitignore
CHANGED
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
|
|
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
|
+
[](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
|
-
|
|
20
|
+
```ruby
|
|
21
|
+
gem 'acts_as_votable', '~> 0.7.0'
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
```ruby
|
|
43
|
+
class Post < ActiveRecord::Base
|
|
44
|
+
acts_as_votable
|
|
45
|
+
end
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
@post = Post.new(:name => 'my post!')
|
|
48
|
+
@post.save
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
67
|
+
By default all votes are positive, so `@user3` has cast a 'good' vote for `@post`.
|
|
61
68
|
|
|
62
|
-
|
|
69
|
+
`@user1`, `@user3`, and `@user5` all voted in favor of `@post`.
|
|
63
70
|
|
|
64
|
-
|
|
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
|
|
69
|
-
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
86
|
+
# negative votes
|
|
87
|
+
@post.downvote_from @user2
|
|
88
|
+
@post.vote :voter => @user2, :vote => 'bad'
|
|
81
89
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
101
|
-
|
|
111
|
+
```ruby
|
|
112
|
+
@post.votes.up.by_type(User).voters
|
|
113
|
+
@post.votes.down.by_type(User).voters
|
|
102
114
|
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
109
|
-
|
|
121
|
+
```ruby
|
|
122
|
+
@post.liked_by @user1
|
|
123
|
+
@post.unliked_by @user1
|
|
110
124
|
|
|
111
|
-
|
|
112
|
-
|
|
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,140 @@ Unvoting works for both positive and negative votes.
|
|
|
117
132
|
|
|
118
133
|
You can add an scope to your vote
|
|
119
134
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
+
```
|
|
144
161
|
|
|
145
162
|
### The Voter
|
|
146
163
|
|
|
147
|
-
You can have your voters
|
|
164
|
+
You can have your voters `acts_as_voter` to provide some reserve functionality.
|
|
148
165
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
166
|
+
```ruby
|
|
167
|
+
class User < ActiveRecord::Base
|
|
168
|
+
acts_as_voter
|
|
169
|
+
end
|
|
152
170
|
|
|
153
|
-
|
|
171
|
+
@user.likes @article
|
|
154
172
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
173
|
+
@article.votes.size # => 1
|
|
174
|
+
@article.likes.size # => 1
|
|
175
|
+
@article.dislikes.size # => 0
|
|
176
|
+
```
|
|
158
177
|
|
|
159
178
|
To check if a voter has voted on a model, you can use ``voted_for?``. You can
|
|
160
179
|
check how the voter voted by using ``voted_as_when_voted_for``.
|
|
161
180
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
181
|
+
```ruby
|
|
182
|
+
@user.likes @comment1
|
|
183
|
+
@user.up_votes @comment2
|
|
184
|
+
# user has not voted on @comment3
|
|
165
185
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
186
|
+
@user.voted_for? @comment1 # => true
|
|
187
|
+
@user.voted_for? @comment2 # => true
|
|
188
|
+
@user.voted_for? @comment3 # => false
|
|
169
189
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
190
|
+
@user.voted_as_when_voted_for @comment1 # => true, he liked it
|
|
191
|
+
@user.voted_as_when_voted_for @comment2 # => false, he didnt like it
|
|
192
|
+
@user.voted_as_when_voted_for @comment3 # => nil, he has yet to vote
|
|
193
|
+
```
|
|
173
194
|
|
|
174
195
|
You can also check whether the voter has voted up or down.
|
|
175
196
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
197
|
+
```ruby
|
|
198
|
+
@user.likes @comment1
|
|
199
|
+
@user.dislikes @comment2
|
|
200
|
+
# user has not voted on @comment3
|
|
179
201
|
|
|
180
|
-
|
|
181
|
-
|
|
202
|
+
@user.voted_up_on? @comment1 # => true
|
|
203
|
+
@user.voted_down_on? @comment1 # => false
|
|
182
204
|
|
|
183
|
-
|
|
184
|
-
|
|
205
|
+
@user.voted_down_on? @comment2 # => true
|
|
206
|
+
@user.voted_up_on? @comment2 # => false
|
|
185
207
|
|
|
186
|
-
|
|
187
|
-
|
|
208
|
+
@user.voted_up_on? @comment3 # => false
|
|
209
|
+
@user.voted_down_on? @comment3 # => false
|
|
210
|
+
```
|
|
188
211
|
|
|
189
|
-
Aliases for methods
|
|
212
|
+
Aliases for methods `voted_up_on?` and `voted_down_on?` are: `voted_up_for?`, `voted_down_for?`, `liked?` and `disliked?`.
|
|
190
213
|
|
|
191
214
|
Also, you can obtain a list of all the objects a user has voted for.
|
|
192
215
|
This returns the actual objects instead of instances of the Vote model.
|
|
193
216
|
All objects are eager loaded
|
|
194
217
|
|
|
195
|
-
|
|
218
|
+
```ruby
|
|
219
|
+
@user.find_voted_items
|
|
196
220
|
|
|
197
|
-
|
|
198
|
-
|
|
221
|
+
@user.find_up_voted_items
|
|
222
|
+
@user.find_liked_items
|
|
199
223
|
|
|
200
|
-
|
|
201
|
-
|
|
224
|
+
@user.find_down_voted_items
|
|
225
|
+
@user.find_disliked_items
|
|
226
|
+
```
|
|
202
227
|
|
|
203
228
|
Members of an individual model that a user has voted for can also be
|
|
204
229
|
displayed. The result is an ActiveRecord Relation.
|
|
205
230
|
|
|
206
|
-
|
|
231
|
+
```ruby
|
|
232
|
+
@user.get_voted Comment
|
|
207
233
|
|
|
208
|
-
|
|
234
|
+
@user.get_up_voted Comment
|
|
209
235
|
|
|
210
|
-
|
|
236
|
+
@user.get_down_voted Comment
|
|
237
|
+
```
|
|
211
238
|
|
|
212
239
|
### Registered Votes
|
|
213
240
|
|
|
214
241
|
Voters can only vote once per model. In this example the 2nd vote does not count
|
|
215
|
-
because
|
|
242
|
+
because `@user` has already voted for `@shoe`.
|
|
216
243
|
|
|
217
|
-
|
|
218
|
-
|
|
244
|
+
```ruby
|
|
245
|
+
@user.likes @shoe
|
|
246
|
+
@user.likes @shoe
|
|
219
247
|
|
|
220
|
-
|
|
221
|
-
|
|
248
|
+
@shoe.votes # => 1
|
|
249
|
+
@shoe.likes # => 1
|
|
250
|
+
```
|
|
222
251
|
|
|
223
|
-
To check if a vote counted, or registered, use vote_registered
|
|
252
|
+
To check if a vote counted, or registered, use `vote_registered?` on your model
|
|
224
253
|
after voting. For example:
|
|
225
254
|
|
|
226
|
-
|
|
227
|
-
|
|
255
|
+
```ruby
|
|
256
|
+
@hat.liked_by @user
|
|
257
|
+
@hat.vote_registered? # => true
|
|
228
258
|
|
|
229
|
-
|
|
230
|
-
|
|
259
|
+
@hat.liked_by => @user
|
|
260
|
+
@hat.vote_registered? # => false, because @user has already voted this way
|
|
231
261
|
|
|
232
|
-
|
|
233
|
-
|
|
262
|
+
@hat.disliked_by @user
|
|
263
|
+
@hat.vote_registered? # => true, because user changed their vote
|
|
234
264
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
265
|
+
@hat.votes.size # => 1
|
|
266
|
+
@hat.positives.size # => 0
|
|
267
|
+
@hat.negatives.size # => 1
|
|
268
|
+
```
|
|
238
269
|
|
|
239
270
|
## Caching
|
|
240
271
|
|
|
@@ -242,37 +273,49 @@ To speed up perform you can add cache columns to your votable model's table. Th
|
|
|
242
273
|
columns will automatically be updated after each vote. For example, if we wanted
|
|
243
274
|
to speed up @post we would use the following migration:
|
|
244
275
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
276
|
+
```ruby
|
|
277
|
+
class AddCachedVotesToPosts < ActiveRecord::Migration
|
|
278
|
+
def self.up
|
|
279
|
+
add_column :posts, :cached_votes_total, :integer, :default => 0
|
|
280
|
+
add_column :posts, :cached_votes_score, :integer, :default => 0
|
|
281
|
+
add_column :posts, :cached_votes_up, :integer, :default => 0
|
|
282
|
+
add_column :posts, :cached_votes_down, :integer, :default => 0
|
|
283
|
+
add_index :posts, :cached_votes_total
|
|
284
|
+
add_index :posts, :cached_votes_score
|
|
285
|
+
add_index :posts, :cached_votes_up
|
|
286
|
+
add_index :posts, :cached_votes_down
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def self.down
|
|
290
|
+
remove_column :posts, :cached_votes_total
|
|
291
|
+
remove_column :posts, :cached_votes_score
|
|
292
|
+
remove_column :posts, :cached_votes_up
|
|
293
|
+
remove_column :posts, :cached_votes_down
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
```
|
|
264
297
|
|
|
265
298
|
## Testing
|
|
266
299
|
|
|
267
|
-
All tests follow the RSpec format and are located in the spec directory
|
|
300
|
+
All tests follow the RSpec format and are located in the spec directory.
|
|
301
|
+
They can be run with:
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
rake spec
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## License
|
|
308
|
+
|
|
309
|
+
Acts as votable is released under the [MIT
|
|
310
|
+
License](http://www.opensource.org/licenses/MIT).
|
|
268
311
|
|
|
269
312
|
## TODO
|
|
270
313
|
|
|
271
314
|
- Pass in a block of options when creating acts_as. Allow for things
|
|
272
315
|
like disabling the aliasing
|
|
273
316
|
|
|
274
|
-
- Smarter language syntax. Example:
|
|
275
|
-
that the user likes, while
|
|
317
|
+
- Smarter language syntax. Example: `@user.likes` will return all of the votables
|
|
318
|
+
that the user likes, while `@user.likes @model` will cast a vote for @model by
|
|
276
319
|
@user.
|
|
277
320
|
|
|
278
321
|
- Need to test a model that is votable as well as a voter
|
data/Rakefile
CHANGED
data/acts_as_votable.gemspec
CHANGED
|
@@ -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
|
|
@@ -27,8 +27,8 @@ module ActsAsVotable
|
|
|
27
27
|
:down_votes => [
|
|
28
28
|
:false_votes, :downs, :downvotes, :dislikes, :negatives
|
|
29
29
|
],
|
|
30
|
-
:
|
|
31
|
-
:unliked_by, :undisliked_by
|
|
30
|
+
:unvote_for => [
|
|
31
|
+
:unvote_up, :unvote_down, :unliked_by, :undisliked_by
|
|
32
32
|
]
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -130,6 +130,10 @@ module ActsAsVotable
|
|
|
130
130
|
self.vote :voter => voter, :vote => false, :vote_scope => options[:vote_scope]
|
|
131
131
|
end
|
|
132
132
|
|
|
133
|
+
def unvote_for voter, options = {}
|
|
134
|
+
self.unvote :voter => voter, :vote_scope => options[:vote_scope]
|
|
135
|
+
end
|
|
136
|
+
|
|
133
137
|
# caching
|
|
134
138
|
def update_cached_votes
|
|
135
139
|
|
|
@@ -154,7 +158,11 @@ module ActsAsVotable
|
|
|
154
158
|
)
|
|
155
159
|
end
|
|
156
160
|
|
|
157
|
-
|
|
161
|
+
if (::ActiveRecord::VERSION::MAJOR == 3) && (::ActiveRecord::VERSION::MINOR != 0)
|
|
162
|
+
self.update_attributes(updates, :without_protection => true) if updates.size > 0
|
|
163
|
+
else
|
|
164
|
+
self.update_attributes(updates) if updates.size > 0
|
|
165
|
+
end
|
|
158
166
|
|
|
159
167
|
end
|
|
160
168
|
|
data/lib/acts_as_votable/vote.rb
CHANGED
|
@@ -5,16 +5,18 @@ module ActsAsVotable
|
|
|
5
5
|
|
|
6
6
|
include Helpers::Words
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
:
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
if ::ActiveRecord::VERSION::MAJOR < 4
|
|
9
|
+
attr_accessible :votable_id, :votable_type,
|
|
10
|
+
:voter_id, :voter_type,
|
|
11
|
+
:votable, :voter,
|
|
12
|
+
:vote_flag, :vote_scope
|
|
13
|
+
end
|
|
12
14
|
|
|
13
15
|
belongs_to :votable, :polymorphic => true
|
|
14
16
|
belongs_to :voter, :polymorphic => true
|
|
15
17
|
|
|
16
|
-
scope :up, where(:vote_flag => true)
|
|
17
|
-
scope :down, where(:vote_flag => false)
|
|
18
|
+
scope :up, lambda{ where(:vote_flag => true) }
|
|
19
|
+
scope :down, lambda{ where(:vote_flag => false) }
|
|
18
20
|
scope :for_type, lambda{ |klass| where(:votable_type => klass) }
|
|
19
21
|
scope :by_type, lambda{ |klass| where(:voter_type => klass) }
|
|
20
22
|
|
|
@@ -5,11 +5,15 @@ module ActsAsVotable
|
|
|
5
5
|
|
|
6
6
|
# allow user to define these
|
|
7
7
|
aliases = {
|
|
8
|
-
:vote_up_for
|
|
9
|
-
:vote_down_for
|
|
10
|
-
:unvote_for
|
|
8
|
+
:vote_up_for => [:likes, :upvotes, :up_votes],
|
|
9
|
+
:vote_down_for => [:dislikes, :downvotes, :down_votes],
|
|
10
|
+
:unvote_for => [:unlike, :undislike],
|
|
11
|
+
:voted_on? => [:voted_for?],
|
|
11
12
|
:voted_up_on? => [:voted_up_for?, :liked?],
|
|
12
|
-
:voted_down_on? => [:voted_down_for?, :disliked?]
|
|
13
|
+
:voted_down_on? => [:voted_down_for?, :disliked?],
|
|
14
|
+
:voted_as_when_voting_on => [:voted_as_when_voted_on, :voted_as_when_voting_for, :voted_as_when_voted_for],
|
|
15
|
+
:find_up_voted_items => [:find_liked_items],
|
|
16
|
+
:find_down_voted_items => [:find_disliked_items]
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
base.class_eval do
|
|
@@ -66,7 +70,6 @@ module ActsAsVotable
|
|
|
66
70
|
:vote_scope => args[:vote_scope], :vote_flag => false)
|
|
67
71
|
votes.size > 0
|
|
68
72
|
end
|
|
69
|
-
alias :voted_down_for? :voted_down_on?
|
|
70
73
|
|
|
71
74
|
def voted_as_when_voting_on votable, args={}
|
|
72
75
|
votes = find_votes(:votable_id => votable.id, :votable_type => votable.class.name,
|
|
@@ -74,7 +77,6 @@ module ActsAsVotable
|
|
|
74
77
|
return nil if votes.size == 0
|
|
75
78
|
return votes.first.vote_flag
|
|
76
79
|
end
|
|
77
|
-
alias :voted_as_when_voted_for :voted_as_when_voting_on
|
|
78
80
|
|
|
79
81
|
def find_votes extra_conditions = {}
|
|
80
82
|
votes.where(extra_conditions)
|
|
@@ -113,12 +115,10 @@ module ActsAsVotable
|
|
|
113
115
|
def find_up_voted_items extra_conditions = {}
|
|
114
116
|
find_voted_items extra_conditions.merge(:vote_flag => true)
|
|
115
117
|
end
|
|
116
|
-
alias_method :find_liked_items, :find_up_voted_items
|
|
117
118
|
|
|
118
119
|
def find_down_voted_items extra_conditions = {}
|
|
119
120
|
find_voted_items extra_conditions.merge(:vote_flag => false)
|
|
120
121
|
end
|
|
121
|
-
alias_method :find_disliked_items, :find_down_voted_items
|
|
122
122
|
|
|
123
123
|
def get_voted klass, extra_conditions = {}
|
|
124
124
|
klass.joins(:votes).merge find_votes(extra_conditions)
|
data/lib/acts_as_votable.rb
CHANGED
|
@@ -11,8 +11,11 @@ class ActsAsVotableMigration < ActiveRecord::Migration
|
|
|
11
11
|
t.timestamps
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
if ActiveRecord::VERSION::MAJOR < 4
|
|
15
|
+
add_index :votes, [:votable_id, :votable_type]
|
|
16
|
+
add_index :votes, [:voter_id, :voter_type]
|
|
17
|
+
end
|
|
18
|
+
|
|
16
19
|
add_index :votes, [:voter_id, :voter_type, :vote_scope]
|
|
17
20
|
add_index :votes, [:votable_id, :votable_type, :vote_scope]
|
|
18
21
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/votable_spec.rb
CHANGED
|
@@ -116,6 +116,12 @@ describe ActsAsVotable::Votable do
|
|
|
116
116
|
@votable.voted_on_by?(@voter).should be true
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
+
it "should be able to unvote a voter" do
|
|
120
|
+
@votable.liked_by(@voter)
|
|
121
|
+
@votable.unliked_by(@voter)
|
|
122
|
+
@votable.voted_on_by?(@voter).should be false
|
|
123
|
+
end
|
|
124
|
+
|
|
119
125
|
it "should unvote a positive vote" do
|
|
120
126
|
@votable.vote :voter => @voter
|
|
121
127
|
@votable.unvote :voter => @voter
|
data/spec/voter_spec.rb
CHANGED
|
@@ -35,6 +35,7 @@ describe ActsAsVotable::Voter do
|
|
|
35
35
|
it "should be voted on after a voter has voted" do
|
|
36
36
|
@votable.vote :voter => @voter
|
|
37
37
|
@voter.voted_on?(@votable).should be true
|
|
38
|
+
@voter.voted_for?(@votable).should be true
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
it "should not be voted on if a voter has not voted" do
|
|
@@ -53,6 +54,7 @@ describe ActsAsVotable::Voter do
|
|
|
53
54
|
|
|
54
55
|
it "should be voted as true when a voter has voted true" do
|
|
55
56
|
@votable.vote :voter => @voter
|
|
57
|
+
@voter.voted_as_when_voted_on(@votable).should be true
|
|
56
58
|
@voter.voted_as_when_voted_for(@votable).should be true
|
|
57
59
|
end
|
|
58
60
|
|
|
@@ -206,6 +208,8 @@ describe ActsAsVotable::Voter do
|
|
|
206
208
|
@votable2.vote :voter => @voter2
|
|
207
209
|
@voter.find_up_voted_items.should include @votable
|
|
208
210
|
@voter.find_up_voted_items.size.should == 1
|
|
211
|
+
@voter.find_liked_items.should include @votable
|
|
212
|
+
@voter.find_liked_items.size.should == 1
|
|
209
213
|
end
|
|
210
214
|
|
|
211
215
|
it 'returns objects that a user has upvoted for, using scope' do
|
|
@@ -242,6 +246,8 @@ describe ActsAsVotable::Voter do
|
|
|
242
246
|
@votable2.vote_down @voter2
|
|
243
247
|
@voter.find_down_voted_items.should include @votable
|
|
244
248
|
@voter.find_down_voted_items.size.should == 1
|
|
249
|
+
@voter.find_disliked_items.should include @votable
|
|
250
|
+
@voter.find_disliked_items.size.should == 1
|
|
245
251
|
end
|
|
246
252
|
|
|
247
253
|
it 'returns objects that a user has downvoted for, using scope' do
|
metadata
CHANGED
|
@@ -1,64 +1,43 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: acts_as_votable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.7.0
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- Ryan
|
|
9
8
|
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date: 2013-
|
|
11
|
+
date: 2013-08-24 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: rspec
|
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
|
17
|
-
none: false
|
|
18
16
|
requirements:
|
|
19
|
-
- -
|
|
17
|
+
- - '>='
|
|
20
18
|
- !ruby/object:Gem::Version
|
|
21
19
|
version: '0'
|
|
22
20
|
type: :development
|
|
23
21
|
prerelease: false
|
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
-
none: false
|
|
26
23
|
requirements:
|
|
27
|
-
- -
|
|
24
|
+
- - '>='
|
|
28
25
|
- !ruby/object:Gem::Version
|
|
29
26
|
version: '0'
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
|
31
28
|
name: sqlite3
|
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
|
33
|
-
none: false
|
|
34
30
|
requirements:
|
|
35
|
-
- -
|
|
31
|
+
- - '='
|
|
36
32
|
- !ruby/object:Gem::Version
|
|
37
|
-
version:
|
|
33
|
+
version: 1.3.7
|
|
38
34
|
type: :development
|
|
39
35
|
prerelease: false
|
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
-
none: false
|
|
42
|
-
requirements:
|
|
43
|
-
- - ! '>='
|
|
44
|
-
- !ruby/object:Gem::Version
|
|
45
|
-
version: '0'
|
|
46
|
-
- !ruby/object:Gem::Dependency
|
|
47
|
-
name: rails
|
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
|
49
|
-
none: false
|
|
50
|
-
requirements:
|
|
51
|
-
- - ! '>='
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: 3.0.0
|
|
54
|
-
type: :runtime
|
|
55
|
-
prerelease: false
|
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
-
none: false
|
|
58
37
|
requirements:
|
|
59
|
-
- -
|
|
38
|
+
- - '='
|
|
60
39
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: 3.
|
|
40
|
+
version: 1.3.7
|
|
62
41
|
description: Rails gem to allowing records to be votable
|
|
63
42
|
email:
|
|
64
43
|
- ryanto
|
|
@@ -67,12 +46,13 @@ extensions: []
|
|
|
67
46
|
extra_rdoc_files: []
|
|
68
47
|
files:
|
|
69
48
|
- .gitignore
|
|
49
|
+
- .travis.yml
|
|
70
50
|
- Gemfile
|
|
71
|
-
- Gemfile.lock
|
|
72
51
|
- README.markdown
|
|
73
52
|
- Rakefile
|
|
74
53
|
- acts_as_votable.gemspec
|
|
75
54
|
- lib/acts_as_votable.rb
|
|
55
|
+
- lib/acts_as_votable/extenders/controller.rb
|
|
76
56
|
- lib/acts_as_votable/extenders/votable.rb
|
|
77
57
|
- lib/acts_as_votable/extenders/voter.rb
|
|
78
58
|
- lib/acts_as_votable/helpers/words.rb
|
|
@@ -88,33 +68,26 @@ files:
|
|
|
88
68
|
- spec/words_spec.rb
|
|
89
69
|
homepage: http://rubygems.org/gems/acts_as_votable
|
|
90
70
|
licenses: []
|
|
71
|
+
metadata: {}
|
|
91
72
|
post_install_message:
|
|
92
73
|
rdoc_options: []
|
|
93
74
|
require_paths:
|
|
94
75
|
- lib
|
|
95
76
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
|
-
none: false
|
|
97
77
|
requirements:
|
|
98
|
-
- -
|
|
78
|
+
- - '>='
|
|
99
79
|
- !ruby/object:Gem::Version
|
|
100
80
|
version: '0'
|
|
101
|
-
segments:
|
|
102
|
-
- 0
|
|
103
|
-
hash: 3405338433430010114
|
|
104
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
|
-
none: false
|
|
106
82
|
requirements:
|
|
107
|
-
- -
|
|
83
|
+
- - '>='
|
|
108
84
|
- !ruby/object:Gem::Version
|
|
109
85
|
version: '0'
|
|
110
|
-
segments:
|
|
111
|
-
- 0
|
|
112
|
-
hash: 3405338433430010114
|
|
113
86
|
requirements: []
|
|
114
87
|
rubyforge_project: acts_as_votable
|
|
115
|
-
rubygems_version:
|
|
88
|
+
rubygems_version: 2.0.3
|
|
116
89
|
signing_key:
|
|
117
|
-
specification_version:
|
|
90
|
+
specification_version: 4
|
|
118
91
|
summary: Rails gem to allowing records to be votable
|
|
119
92
|
test_files:
|
|
120
93
|
- spec/spec_helper.rb
|
data/Gemfile.lock
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
acts_as_votable (0.5.0)
|
|
5
|
-
rails (>= 3.0.0)
|
|
6
|
-
|
|
7
|
-
GEM
|
|
8
|
-
remote: http://rubygems.org/
|
|
9
|
-
specs:
|
|
10
|
-
actionmailer (3.2.11)
|
|
11
|
-
actionpack (= 3.2.11)
|
|
12
|
-
mail (~> 2.4.4)
|
|
13
|
-
actionpack (3.2.11)
|
|
14
|
-
activemodel (= 3.2.11)
|
|
15
|
-
activesupport (= 3.2.11)
|
|
16
|
-
builder (~> 3.0.0)
|
|
17
|
-
erubis (~> 2.7.0)
|
|
18
|
-
journey (~> 1.0.4)
|
|
19
|
-
rack (~> 1.4.0)
|
|
20
|
-
rack-cache (~> 1.2)
|
|
21
|
-
rack-test (~> 0.6.1)
|
|
22
|
-
sprockets (~> 2.2.1)
|
|
23
|
-
activemodel (3.2.11)
|
|
24
|
-
activesupport (= 3.2.11)
|
|
25
|
-
builder (~> 3.0.0)
|
|
26
|
-
activerecord (3.2.11)
|
|
27
|
-
activemodel (= 3.2.11)
|
|
28
|
-
activesupport (= 3.2.11)
|
|
29
|
-
arel (~> 3.0.2)
|
|
30
|
-
tzinfo (~> 0.3.29)
|
|
31
|
-
activeresource (3.2.11)
|
|
32
|
-
activemodel (= 3.2.11)
|
|
33
|
-
activesupport (= 3.2.11)
|
|
34
|
-
activesupport (3.2.11)
|
|
35
|
-
i18n (~> 0.6)
|
|
36
|
-
multi_json (~> 1.0)
|
|
37
|
-
arel (3.0.2)
|
|
38
|
-
builder (3.0.4)
|
|
39
|
-
diff-lcs (1.1.3)
|
|
40
|
-
erubis (2.7.0)
|
|
41
|
-
hike (1.2.1)
|
|
42
|
-
i18n (0.6.1)
|
|
43
|
-
journey (1.0.4)
|
|
44
|
-
json (1.7.6)
|
|
45
|
-
mail (2.4.4)
|
|
46
|
-
i18n (>= 0.4.0)
|
|
47
|
-
mime-types (~> 1.16)
|
|
48
|
-
treetop (~> 1.4.8)
|
|
49
|
-
mime-types (1.19)
|
|
50
|
-
multi_json (1.5.0)
|
|
51
|
-
polyglot (0.3.3)
|
|
52
|
-
rack (1.4.4)
|
|
53
|
-
rack-cache (1.2)
|
|
54
|
-
rack (>= 0.4)
|
|
55
|
-
rack-ssl (1.3.2)
|
|
56
|
-
rack
|
|
57
|
-
rack-test (0.6.2)
|
|
58
|
-
rack (>= 1.0)
|
|
59
|
-
rails (3.2.11)
|
|
60
|
-
actionmailer (= 3.2.11)
|
|
61
|
-
actionpack (= 3.2.11)
|
|
62
|
-
activerecord (= 3.2.11)
|
|
63
|
-
activeresource (= 3.2.11)
|
|
64
|
-
activesupport (= 3.2.11)
|
|
65
|
-
bundler (~> 1.0)
|
|
66
|
-
railties (= 3.2.11)
|
|
67
|
-
railties (3.2.11)
|
|
68
|
-
actionpack (= 3.2.11)
|
|
69
|
-
activesupport (= 3.2.11)
|
|
70
|
-
rack-ssl (~> 1.3.2)
|
|
71
|
-
rake (>= 0.8.7)
|
|
72
|
-
rdoc (~> 3.4)
|
|
73
|
-
thor (>= 0.14.6, < 2.0)
|
|
74
|
-
rake (10.0.3)
|
|
75
|
-
rdoc (3.12)
|
|
76
|
-
json (~> 1.4)
|
|
77
|
-
rspec (2.9.0)
|
|
78
|
-
rspec-core (~> 2.9.0)
|
|
79
|
-
rspec-expectations (~> 2.9.0)
|
|
80
|
-
rspec-mocks (~> 2.9.0)
|
|
81
|
-
rspec-core (2.9.0)
|
|
82
|
-
rspec-expectations (2.9.1)
|
|
83
|
-
diff-lcs (~> 1.1.3)
|
|
84
|
-
rspec-mocks (2.9.0)
|
|
85
|
-
sprockets (2.2.2)
|
|
86
|
-
hike (~> 1.2)
|
|
87
|
-
multi_json (~> 1.0)
|
|
88
|
-
rack (~> 1.0)
|
|
89
|
-
tilt (~> 1.1, != 1.3.0)
|
|
90
|
-
sqlite3 (1.3.5)
|
|
91
|
-
thor (0.16.0)
|
|
92
|
-
tilt (1.3.3)
|
|
93
|
-
treetop (1.4.12)
|
|
94
|
-
polyglot
|
|
95
|
-
polyglot (>= 0.3.1)
|
|
96
|
-
tzinfo (0.3.35)
|
|
97
|
-
|
|
98
|
-
PLATFORMS
|
|
99
|
-
ruby
|
|
100
|
-
|
|
101
|
-
DEPENDENCIES
|
|
102
|
-
acts_as_votable!
|
|
103
|
-
rspec
|
|
104
|
-
sqlite3
|