acts_as_votable 0.10.0 → 0.13.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.
Files changed (52) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/main.yml +44 -0
  3. data/.gitignore +10 -6
  4. data/.rubocop.yml +121 -0
  5. data/.ruby-version +1 -0
  6. data/Appraisals +23 -0
  7. data/Gemfile +3 -14
  8. data/{README.markdown → README.md} +87 -52
  9. data/Rakefile +6 -4
  10. data/acts_as_votable.gemspec +12 -7
  11. data/gemfiles/.bundle/config +2 -0
  12. data/gemfiles/rails_4.gemfile +7 -0
  13. data/gemfiles/rails_5.gemfile +7 -0
  14. data/gemfiles/rails_5_1.gemfile +7 -0
  15. data/gemfiles/rails_5_2.gemfile +7 -0
  16. data/gemfiles/rails_6.gemfile +8 -0
  17. data/gemfiles/rails_6_1.gemfile +8 -0
  18. data/gemfiles/rails_6_rc1.gemfile +8 -0
  19. data/lib/acts_as_votable.rb +9 -9
  20. data/lib/acts_as_votable/cacheable.rb +174 -0
  21. data/lib/acts_as_votable/extenders/controller.rb +3 -4
  22. data/lib/acts_as_votable/extenders/votable.rb +17 -6
  23. data/lib/acts_as_votable/extenders/voter.rb +4 -6
  24. data/lib/acts_as_votable/helpers/words.rb +7 -10
  25. data/lib/acts_as_votable/version.rb +3 -1
  26. data/lib/acts_as_votable/votable.rb +74 -194
  27. data/lib/acts_as_votable/vote.rb +10 -12
  28. data/lib/acts_as_votable/voter.rb +55 -56
  29. data/lib/generators/acts_as_votable/migration/migration_generator.rb +25 -4
  30. data/lib/generators/acts_as_votable/migration/templates/active_record/{migration.rb → migration.erb} +1 -6
  31. data/spec/factories/votable.rb +6 -0
  32. data/spec/factories/votable_cache.rb +6 -0
  33. data/spec/factories/votable_cache_update_attributes.rb +6 -0
  34. data/spec/factories/votable_cache_update_columns.rb +6 -0
  35. data/spec/factories/votable_child_of_sti_not_votable.rb +6 -0
  36. data/spec/factories/votable_child_of_sti_votable.rb +6 -0
  37. data/spec/factories/votable_voter.rb +6 -0
  38. data/spec/factories/vote.rb +6 -0
  39. data/spec/factories/voter.rb +6 -0
  40. data/spec/generators/active_record_generator_spec.rb +13 -0
  41. data/spec/shared_example/votable_model.rb +542 -0
  42. data/spec/shared_example/voter_model.rb +280 -0
  43. data/spec/spec_helper.rb +28 -18
  44. data/spec/support/factory_bot.rb +9 -0
  45. data/spec/votable_spec.rb +10 -9
  46. data/spec/votable_voter_spec.rb +12 -12
  47. data/spec/voter_spec.rb +9 -10
  48. data/spec/words_spec.rb +9 -12
  49. metadata +116 -26
  50. data/.travis.yml +0 -25
  51. data/spec/shared_example/votable_model_spec.rb +0 -421
  52. data/spec/shared_example/voter_model_spec.rb +0 -279
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c2beddd83fe6f3062fdfb1599953b34d942f6ac8
4
- data.tar.gz: 8bfb3b0bb95722935fb3eb315da58c619f583921
2
+ SHA256:
3
+ metadata.gz: b1843c2e0892abc19c5ecc63dd48e38fe8d48e1cdb7affc3c90d67b0419725e1
4
+ data.tar.gz: b05a72a3a7310c362233e9d54301a695a03fb72c9fb6068b2fde8e58d1e238bb
5
5
  SHA512:
6
- metadata.gz: cbe9cba192df3d698531c14a10f8340b78642cd51288b582b064384ea48931345900c74a499598b541ca2662230d262be6acc0f26d2db9a3763539140ec08683
7
- data.tar.gz: 03948b37befab6d39cd621b63d6e32cb2404b4850f2d5b2e2bece1674bcbaa13bcc4aff7e023f30aeff3330c809fdf9eb28b7d28d5ae6d6685c287c5167a90c1
6
+ metadata.gz: a125832f11dd75fa540f90791b5bdc092b92ade7c2a34218947fa1621aae21487eb38d8664636d1113885bb878927805a10f0db5edb786c48a8339832859bd68
7
+ data.tar.gz: 23bb31cc323d1173f982b2d12895b834e26b1ede7a6293cc1343538140f2fe3f7f9c0c89daf4de4ea67d72a69b4b4bbca2c4ec53555500ec965f26ca8fb1f475
@@ -0,0 +1,44 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches:
5
+ - master
6
+ pull_request:
7
+ branches:
8
+ - master
9
+
10
+ jobs:
11
+ tests:
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ os:
16
+ - ubuntu
17
+ ruby:
18
+ - 2.5
19
+ - 2.6
20
+ - 2.7
21
+ gemfile:
22
+ - gemfiles/rails_5_1.gemfile
23
+ - gemfiles/rails_5_2.gemfile
24
+ - gemfiles/rails_6.gemfile
25
+ - gemfiles/rails_6_1.gemfile
26
+ continue-on-error:
27
+ - false
28
+
29
+ env:
30
+ BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
31
+ runs-on: ${{ matrix.os }}-latest
32
+ continue-on-error: ${{ matrix.continue-on-error }}
33
+ steps:
34
+ - name: Checkout
35
+ uses: actions/checkout@v2
36
+ - name: Setup Ruby
37
+ uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: ${{ matrix.ruby }}
40
+ bundler-cache: true
41
+ - name: Test
42
+ run: bundle exec rake spec
43
+
44
+ # use this
data/.gitignore CHANGED
@@ -1,6 +1,10 @@
1
- pkg/*
2
- *.gem
3
- .bundle
4
- nbproject/*
5
- Gemfile.lock
6
- bin
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /gemfiles/*.gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
@@ -0,0 +1,121 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.2
3
+ # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
4
+ # to ignore them, so only the ones explicitly set in this file are enabled.
5
+ DisabledByDefault: true
6
+
7
+ # Prefer &&/|| over and/or.
8
+ Style/AndOr:
9
+ Enabled: true
10
+
11
+ # Do not use braces for hash literals when they are the last argument of a
12
+ # method call.
13
+ Style/BracesAroundHashParameters:
14
+ Enabled: true
15
+ EnforcedStyle: context_dependent
16
+
17
+ # Align `when` with `case`.
18
+ Layout/CaseIndentation:
19
+ Enabled: true
20
+
21
+ # Align comments with method definitions.
22
+ Layout/CommentIndentation:
23
+ Enabled: true
24
+
25
+ Layout/EmptyLineAfterMagicComment:
26
+ Enabled: true
27
+
28
+ # In a regular class definition, no empty lines around the body.
29
+ Layout/EmptyLinesAroundClassBody:
30
+ Enabled: true
31
+
32
+ # In a regular method definition, no empty lines around the body.
33
+ Layout/EmptyLinesAroundMethodBody:
34
+ Enabled: true
35
+
36
+ # In a regular module definition, no empty lines around the body.
37
+ Layout/EmptyLinesAroundModuleBody:
38
+ Enabled: true
39
+
40
+ Layout/FirstParameterIndentation:
41
+ Enabled: true
42
+
43
+ # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
44
+ Style/HashSyntax:
45
+ Enabled: true
46
+
47
+ # Two spaces, no tabs (for indentation).
48
+ Layout/IndentationWidth:
49
+ Enabled: true
50
+
51
+ Layout/SpaceAfterColon:
52
+ Enabled: true
53
+
54
+ Layout/SpaceAfterComma:
55
+ Enabled: true
56
+
57
+ Layout/SpaceAroundEqualsInParameterDefault:
58
+ Enabled: true
59
+
60
+ Layout/SpaceAroundKeyword:
61
+ Enabled: true
62
+
63
+ Layout/SpaceAroundOperators:
64
+ Enabled: true
65
+
66
+ Layout/SpaceBeforeFirstArg:
67
+ Enabled: true
68
+
69
+ # Defining a method with parameters needs parentheses.
70
+ Style/MethodDefParentheses:
71
+ Enabled: true
72
+
73
+ Style/FrozenStringLiteralComment:
74
+ Enabled: true
75
+ EnforcedStyle: always
76
+
77
+ # Use `foo {}` not `foo{}`.
78
+ Layout/SpaceBeforeBlockBraces:
79
+ Enabled: true
80
+
81
+ # Use `foo { bar }` not `foo {bar}`.
82
+ Layout/SpaceInsideBlockBraces:
83
+ Enabled: true
84
+
85
+ # Use `{ a: 1 }` not `{a:1}`.
86
+ Layout/SpaceInsideHashLiteralBraces:
87
+ Enabled: true
88
+
89
+ Layout/SpaceInsideParens:
90
+ Enabled: true
91
+
92
+ # Check quotes usage according to lint rule below.
93
+ Style/StringLiterals:
94
+ Enabled: true
95
+ EnforcedStyle: double_quotes
96
+
97
+ # Detect hard tabs, no hard tabs.
98
+ Layout/Tab:
99
+ Enabled: true
100
+
101
+ # Blank lines should not have any spaces.
102
+ Layout/TrailingBlankLines:
103
+ Enabled: true
104
+
105
+ # No trailing whitespace.
106
+ Layout/TrailingWhitespace:
107
+ Enabled: true
108
+
109
+ # Use quotes for string literals when they are enough.
110
+ Style/UnneededPercentQ:
111
+ Enabled: true
112
+
113
+ # Align `end` with the matching keyword or starting expression except for
114
+ # assignments, where it should be aligned with the LHS.
115
+ Lint/EndAlignment:
116
+ Enabled: true
117
+ EnforcedStyleAlignWith: variable
118
+
119
+ # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
120
+ Lint/RequireParentheses:
121
+ Enabled: true
@@ -0,0 +1 @@
1
+ 2.5.3
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ appraise "rails-4" do
4
+ gem "rails", "4.2.11"
5
+ end
6
+
7
+ appraise "rails-5-1" do
8
+ gem "rails", "5.1.7"
9
+ end
10
+
11
+ appraise "rails-5-2" do
12
+ gem "rails", "5.2.4"
13
+ end
14
+
15
+ appraise "rails-6" do
16
+ gem "rails", "6.0.3"
17
+ gem "sqlite3", "~> 1.4"
18
+ end
19
+
20
+ appraise "rails-6-1" do
21
+ gem "rails", "6.1.0"
22
+ gem "sqlite3", "~> 1.4"
23
+ end
data/Gemfile CHANGED
@@ -1,17 +1,6 @@
1
- source 'https://rubygems.org'
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
2
4
 
3
5
  # Specify your gem's dependencies in acts_as_votable.gemspec
4
6
  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
@@ -1,6 +1,6 @@
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)
3
+ ![Build status](https://github.com/ryanto/acts_as_votable/workflows/CI/badge.svg)
4
4
 
5
5
  Acts As Votable is a Ruby Gem specifically written for Rails/ActiveRecord models.
6
6
  The main goals of this gem are:
@@ -15,17 +15,15 @@ The main goals of this gem are:
15
15
 
16
16
  ### Supported Ruby and Rails versions
17
17
 
18
- * Ruby 1.8.7, 1.9.2, 1.9.3
19
- * Ruby 2.0.0, 2.1.0
20
- * Rails 3.0, 3.1, 3.2
21
- * Rails 4.0, 4.1+
18
+ * Ruby >= 2.3.0
19
+ * Rails >= 4
22
20
 
23
21
  ### Install
24
22
 
25
- Just add the following to your Gemfile.
23
+ Just add the following to your Gemfile to install the latest release.
26
24
 
27
25
  ```ruby
28
- gem 'acts_as_votable', '~> 0.10.0'
26
+ gem 'acts_as_votable'
29
27
  ```
30
28
 
31
29
  And follow that up with a ``bundle install``.
@@ -36,7 +34,7 @@ Acts As Votable uses a votes table to store all voting information. To
36
34
  generate and run the migration just use.
37
35
 
38
36
  rails generate acts_as_votable:migration
39
- rake db:migrate
37
+ rails db:migrate
40
38
 
41
39
  You will get a performance increase by adding in cached columns to your model's
42
40
  tables. You will have to do this manually through your own migrations. See the
@@ -47,7 +45,7 @@ caching section of this document for more information.
47
45
  ### Votable Models
48
46
 
49
47
  ```ruby
50
- class Post < ActiveRecord::Base
48
+ class Post < ApplicationRecord
51
49
  acts_as_votable
52
50
  end
53
51
 
@@ -96,10 +94,12 @@ Revisiting the previous example of code.
96
94
 
97
95
  # tally them up!
98
96
  @post.votes_for.size # => 5
97
+ @post.weighted_total => 5
99
98
  @post.get_likes.size # => 3
100
99
  @post.get_upvotes.size # => 3
101
100
  @post.get_dislikes.size # => 2
102
101
  @post.get_downvotes.size # => 2
102
+ @post.weighted_score => 1
103
103
  ```
104
104
 
105
105
  Active Record scopes are provided to make life easier.
@@ -109,7 +109,7 @@ Active Record scopes are provided to make life easier.
109
109
  @post.votes_for.down
110
110
  @user1.votes.up
111
111
  @user1.votes.down
112
- @user1.votes.up.by_type(Post)
112
+ @user1.votes.up.for_type(Post)
113
113
  ```
114
114
 
115
115
  Once scoping is complete, you can also trigger a get for the
@@ -137,7 +137,7 @@ Unvoting works for both positive and negative votes.
137
137
 
138
138
  ### Examples with scopes
139
139
 
140
- You can add an scope to your vote
140
+ You can add a scope to your vote
141
141
 
142
142
  ```ruby
143
143
  # positive votes
@@ -192,15 +192,15 @@ You can add weight to your vote. The default value is 1.
192
192
  You can have your voters `acts_as_voter` to provide some reserve functionality.
193
193
 
194
194
  ```ruby
195
- class User < ActiveRecord::Base
195
+ class User < ApplicationRecord
196
196
  acts_as_voter
197
197
  end
198
198
 
199
199
  @user.likes @article
200
200
 
201
- @article.votes.size # => 1
202
- @article.likes.size # => 1
203
- @article.dislikes.size # => 0
201
+ @article.votes_for.size # => 1
202
+ @article.get_likes.size # => 1
203
+ @article.get_dislikes.size # => 0
204
204
  ```
205
205
 
206
206
  To check if a voter has voted on a model, you can use ``voted_for?``. You can
@@ -215,9 +215,9 @@ check how the voter voted by using ``voted_as_when_voted_for``.
215
215
  @user.voted_for? @comment2 # => true
216
216
  @user.voted_for? @comment3 # => false
217
217
 
218
- @user.voted_as_when_voted_for @comment1 # => true, he liked it
219
- @user.voted_as_when_voted_for @comment2 # => false, he didnt like it
220
- @user.voted_as_when_voted_for @comment3 # => nil, he has yet to vote
218
+ @user.voted_as_when_voted_for @comment1 # => true, user liked it
219
+ @user.voted_as_when_voted_for @comment2 # => false, user didnt like it
220
+ @user.voted_as_when_voted_for @comment3 # => nil, user has yet to vote
221
221
  ```
222
222
 
223
223
  You can also check whether the voter has voted up or down.
@@ -273,8 +273,8 @@ because `@user` has already voted for `@shoe`.
273
273
  @user.likes @shoe
274
274
  @user.likes @shoe
275
275
 
276
- @shoe.votes # => 1
277
- @shoe.likes # => 1
276
+ @shoe.votes_for.size # => 1
277
+ @shoe.get_likes.size # => 1
278
278
  ```
279
279
 
280
280
  To check if a vote counted, or registered, use `vote_registered?` on your model
@@ -290,9 +290,9 @@ after voting. For example:
290
290
  @hat.disliked_by @user
291
291
  @hat.vote_registered? # => true, because user changed their vote
292
292
 
293
- @hat.votes.size # => 1
294
- @hat.positives.size # => 0
295
- @hat.negatives.size # => 1
293
+ @hat.votes_for.size # => 1
294
+ @hat.get_positives.size # => 0
295
+ @hat.get_negatives.size # => 1
296
296
  ```
297
297
 
298
298
  To permit duplicates entries of a same voter, use option duplicate. Also notice that this
@@ -310,35 +310,71 @@ to speed up @post we would use the following migration:
310
310
 
311
311
  ```ruby
312
312
  class AddCachedVotesToPosts < ActiveRecord::Migration
313
- def self.up
314
- add_column :posts, :cached_votes_total, :integer, :default => 0
315
- add_column :posts, :cached_votes_score, :integer, :default => 0
316
- add_column :posts, :cached_votes_up, :integer, :default => 0
317
- add_column :posts, :cached_votes_down, :integer, :default => 0
318
- add_column :posts, :cached_weighted_score, :integer, :default => 0
319
- add_column :posts, :cached_weighted_total, :integer, :default => 0
320
- add_index :posts, :cached_votes_total
321
- add_index :posts, :cached_votes_score
322
- add_index :posts, :cached_votes_up
323
- add_index :posts, :cached_votes_down
324
- add_index :posts, :cached_weighted_score
325
- add_index :posts, :cached_weighted_total
313
+ def change
314
+ change_table :posts do |t|
315
+ t.integer :cached_votes_total, default: 0
316
+ t.integer :cached_votes_score, default: 0
317
+ t.integer :cached_votes_up, default: 0
318
+ t.integer :cached_votes_down, default: 0
319
+ t.integer :cached_weighted_score, default: 0
320
+ t.integer :cached_weighted_total, default: 0
321
+ t.float :cached_weighted_average, default: 0.0
322
+ end
326
323
 
327
324
  # Uncomment this line to force caching of existing votes
328
325
  # Post.find_each(&:update_cached_votes)
329
326
  end
327
+ end
328
+ ```
329
+
330
+ If you have a scope for your vote, let's say `subscribe`, your migration will be slightly different like below:
330
331
 
331
- def self.down
332
- remove_column :posts, :cached_votes_total
333
- remove_column :posts, :cached_votes_score
334
- remove_column :posts, :cached_votes_up
335
- remove_column :posts, :cached_votes_down
336
- remove_column :posts, :cached_weighted_score
337
- remove_column :posts, :cached_weighted_total
332
+ ```ruby
333
+ class AddCachedVotesToPosts < ActiveRecord::Migration
334
+ def change
335
+ change_table :posts do |t|
336
+ t.integer :cached_scoped_subscribe_votes_total, default: 0
337
+ t.integer :cached_scoped_subscribe_votes_score, default: 0
338
+ t.integer :cached_scoped_subscribe_votes_up, default: 0
339
+ t.integer :cached_scoped_subscribe_votes_down, default: 0
340
+ t.integer :cached_weighted_subscribe_score, default: 0
341
+ t.integer :cached_weighted_subscribe_total, default: 0
342
+ t.float :cached_weighted_subscribe_average, default: 0.0
343
+ end
338
344
  end
339
345
  end
340
346
  ```
341
347
 
348
+ `cached_weighted_average` can be helpful for a rating system, e.g.:
349
+
350
+ Order by average rating:
351
+
352
+ ```ruby
353
+ Post.order(:cached_weighted_average => :desc)
354
+ ```
355
+
356
+ Display average rating:
357
+
358
+ ```erb
359
+ <%= post.weighted_average.round(2) %> / 5
360
+ <!-- 3.5 / 5 -->
361
+ ```
362
+ ## updated_at at Votable model
363
+
364
+ You can control whether `updated_at` column of votable model will be touched or
365
+ not by passing `cacheable_strategy` option to `acts_as_votable` method.
366
+
367
+ By default, `update` strategy is used. Pass `:update_columns` as
368
+ `cacheable_strategy` if you don't want to touch model's `updated_at` column.
369
+ ```ruby
370
+ class Post < ApplicationRecord
371
+ acts_as_votable cacheable_strategy: :update_columns
372
+ end
373
+ ```
374
+
375
+ NOTE: this option does not work for ActiveRecord < 3.1
376
+
377
+
342
378
  ## Testing
343
379
 
344
380
  All tests follow the RSpec format and are located in the spec directory.
@@ -348,20 +384,20 @@ They can be run with:
348
384
  rake spec
349
385
  ```
350
386
 
351
- ## Changes
387
+ ## Changes
352
388
 
353
- ### Fixes for votable voter model
389
+ ### Fixes for votable voter model
354
390
 
355
- In version 0.8.0, there is bugs for a model that is both votable and voter.
391
+ In version 0.8.0, there are bugs for a model that is both votable and voter.
356
392
  Some name-conflicting methods are renamed:
357
- + Renamed Votable.votes to votes_for
393
+ + Renamed Votable.votes to votes_for
358
394
  + Renamed Votable.vote to vote_by,
359
395
  + Removed Votable.vote_by alias (was an alias for :vote_up)
360
396
  + Renamed Votable.unvote_for to unvote_by
361
397
  + Renamed Votable.find_votes to find_votes_for
362
- + Renamed Votable.up_votes to get_upvotes
398
+ + Renamed Votable.up_votes to get_upvotes
363
399
  + and its aliases :get_true_votes, :get_ups, :get_upvotes, :get_likes, :get_positives, :get_for_votes
364
- + Renamed Votable.down_votes to get_downvotes
400
+ + Renamed Votable.down_votes to get_downvotes
365
401
  + and its aliases :get_false_votes, :get_downs, :get_downvotes, :get_dislikes, :get_negatives
366
402
 
367
403
 
@@ -370,7 +406,7 @@ Some name-conflicting methods are renamed:
370
406
  Acts as votable is released under the [MIT
371
407
  License](http://www.opensource.org/licenses/MIT).
372
408
 
373
- ## TODO
409
+ ## Next steps
374
410
 
375
411
  - Pass in a block of options when creating acts_as. Allow for things
376
412
  like disabling the aliasing
@@ -379,8 +415,7 @@ License](http://www.opensource.org/licenses/MIT).
379
415
  that the user likes, while `@user.likes @model` will cast a vote for @model by
380
416
  @user.
381
417
 
382
-
383
418
  - The aliased methods are referred to by using the terms 'up/down' and/or
384
- 'true/false'. Need to come up with guidelines for naming these methods.
419
+ 'true/false'. Need to come up with guidelines for naming these methods.
385
420
 
386
421
  - Create more aliases. Specifically for counting votes and finding votes.