acts_as_votable 0.10.0 → 0.11.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -6
  3. data/.rubocop.yml +121 -0
  4. data/.travis.yml +12 -23
  5. data/Appraisals +13 -0
  6. data/Gemfile +3 -14
  7. data/README.markdown +80 -13
  8. data/Rakefile +6 -4
  9. data/acts_as_votable.gemspec +12 -5
  10. data/gemfiles/.bundle/config +2 -0
  11. data/gemfiles/rails_4.gemfile +7 -0
  12. data/gemfiles/rails_4.gemfile.lock +159 -0
  13. data/gemfiles/rails_5.gemfile +7 -0
  14. data/gemfiles/rails_5.gemfile.lock +166 -0
  15. data/gemfiles/rails_5_1.gemfile +7 -0
  16. data/gemfiles/rails_5_1.gemfile.lock +166 -0
  17. data/lib/acts_as_votable.rb +9 -9
  18. data/lib/acts_as_votable/cacheable.rb +174 -0
  19. data/lib/acts_as_votable/extenders/controller.rb +3 -4
  20. data/lib/acts_as_votable/extenders/votable.rb +17 -6
  21. data/lib/acts_as_votable/extenders/voter.rb +4 -6
  22. data/lib/acts_as_votable/helpers/words.rb +7 -10
  23. data/lib/acts_as_votable/version.rb +3 -1
  24. data/lib/acts_as_votable/votable.rb +50 -187
  25. data/lib/acts_as_votable/vote.rb +10 -12
  26. data/lib/acts_as_votable/voter.rb +52 -53
  27. data/lib/generators/acts_as_votable/migration/migration_generator.rb +19 -4
  28. data/lib/generators/acts_as_votable/migration/templates/active_record/{migration.rb → migration.erb} +1 -6
  29. data/spec/factories/votable.rb +6 -0
  30. data/spec/factories/votable_cache.rb +6 -0
  31. data/spec/factories/votable_cache_update_attributes.rb +6 -0
  32. data/spec/factories/votable_cache_update_columns.rb +6 -0
  33. data/spec/factories/votable_child_of_sti_not_votable.rb +6 -0
  34. data/spec/factories/votable_child_of_sti_votable.rb +6 -0
  35. data/spec/factories/votable_voter.rb +6 -0
  36. data/spec/factories/vote.rb +6 -0
  37. data/spec/factories/voter.rb +6 -0
  38. data/spec/generators/active_record_generator_spec.rb +13 -0
  39. data/spec/shared_example/votable_model.rb +506 -0
  40. data/spec/shared_example/voter_model.rb +280 -0
  41. data/spec/spec_helper.rb +28 -18
  42. data/spec/support/factory_girl.rb +10 -0
  43. data/spec/votable_spec.rb +10 -9
  44. data/spec/votable_voter_spec.rb +12 -12
  45. data/spec/voter_spec.rb +9 -10
  46. data/spec/words_spec.rb +9 -12
  47. metadata +98 -27
  48. data/spec/shared_example/votable_model_spec.rb +0 -421
  49. data/spec/shared_example/voter_model_spec.rb +0 -279
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c2beddd83fe6f3062fdfb1599953b34d942f6ac8
4
- data.tar.gz: 8bfb3b0bb95722935fb3eb315da58c619f583921
3
+ metadata.gz: ec62f24bb2a85474f561c476a47007e333dae16f
4
+ data.tar.gz: ab88ccd51c8d63225b05b7f6443056cd0defe2a5
5
5
  SHA512:
6
- metadata.gz: cbe9cba192df3d698531c14a10f8340b78642cd51288b582b064384ea48931345900c74a499598b541ca2662230d262be6acc0f26d2db9a3763539140ec08683
7
- data.tar.gz: 03948b37befab6d39cd621b63d6e32cb2404b4850f2d5b2e2bece1674bcbaa13bcc4aff7e023f30aeff3330c809fdf9eb28b7d28d5ae6d6685c287c5167a90c1
6
+ metadata.gz: be0133a6030a9c0d83a6753b82360c100ed998a608f98829fd97bc4cbbf27f61990fb1bbc9eac9b9b46b0d4d7e122556e3fce47eb59eb7bf5d42a71a1f895512
7
+ data.tar.gz: ec1ee10e398a40bb5b20a568265334194e29ca8b05b75a8e8f8c87076e9d187f72225124704af321ffa3b615853906b51daf96a4837074f97bdda4cbe27a28a2
data/.gitignore CHANGED
@@ -1,6 +1,9 @@
1
- pkg/*
2
- *.gem
3
- .bundle
4
- nbproject/*
5
- Gemfile.lock
6
- bin
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /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
@@ -1,25 +1,14 @@
1
1
  language: ruby
2
+
3
+ cache: bundler
4
+
2
5
  rvm:
3
- - 1.8.7
4
- - 1.9.2
5
- - 1.9.3
6
- - 2.0.0
7
- - 2.1.0
8
- env:
9
- - "RAILS_VERSION=3.0.0"
10
- - "RAILS_VERSION=3.1.0"
11
- - "RAILS_VERSION=3.2.0"
12
- - "RAILS_VERSION=4.0.0"
13
- - "RAILS_VERSION=4.1.0"
14
- matrix:
15
- exclude:
16
- - rvm: 1.8.7
17
- env: "RAILS_VERSION=4.0.0"
18
- - rvm: 1.9.2
19
- env: "RAILS_VERSION=4.0.0"
20
- - rvm: 1.8.7
21
- env: "RAILS_VERSION=4.1.0"
22
- - rvm: 1.9.2
23
- env: "RAILS_VERSION=4.1.0"
24
- - rvm: 1.9.3
25
- env: "RAILS_VERSION=4.1.0"
6
+ - 2.2.7
7
+ - 2.3.4
8
+ - 2.4.1
9
+
10
+ gemfile:
11
+ - gemfiles/rails_4.gemfile
12
+ - gemfiles/rails_5.gemfile
13
+ - gemfiles/rails_5_1.gemfile
14
+
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ appraise "rails-4" do
4
+ gem "rails", "4.2.9"
5
+ end
6
+
7
+ appraise "rails-5" do
8
+ gem "rails", "5.0.5"
9
+ end
10
+
11
+ appraise "rails-5-1" do
12
+ gem "rails", "5.1.4"
13
+ 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,7 @@
1
1
  # Acts As Votable (aka Acts As Likeable)
2
2
 
3
3
  [![Build Status](https://travis-ci.org/ryanto/acts_as_votable.png)](https://travis-ci.org/ryanto/acts_as_votable)
4
+ [![Code Climate](https://codeclimate.com/github/ryanto/acts_as_votable.png)](https://codeclimate.com/github/ryanto/acts_as_votable)
4
5
 
5
6
  Acts As Votable is a Ruby Gem specifically written for Rails/ActiveRecord models.
6
7
  The main goals of this gem are:
@@ -15,14 +16,13 @@ The main goals of this gem are:
15
16
 
16
17
  ### Supported Ruby and Rails versions
17
18
 
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
19
+ * Ruby 2.2.0, 2.3.0 and 2.4.0
21
20
  * Rails 4.0, 4.1+
21
+ * Rails 5.0, 5.1
22
22
 
23
23
  ### Install
24
24
 
25
- Just add the following to your Gemfile.
25
+ Just add the following to your Gemfile to install the latest release.
26
26
 
27
27
  ```ruby
28
28
  gem 'acts_as_votable', '~> 0.10.0'
@@ -96,10 +96,12 @@ Revisiting the previous example of code.
96
96
 
97
97
  # tally them up!
98
98
  @post.votes_for.size # => 5
99
+ @post.weighted_total => 5
99
100
  @post.get_likes.size # => 3
100
101
  @post.get_upvotes.size # => 3
101
102
  @post.get_dislikes.size # => 2
102
103
  @post.get_downvotes.size # => 2
104
+ @post.weighted_score => 1
103
105
  ```
104
106
 
105
107
  Active Record scopes are provided to make life easier.
@@ -109,7 +111,7 @@ Active Record scopes are provided to make life easier.
109
111
  @post.votes_for.down
110
112
  @user1.votes.up
111
113
  @user1.votes.down
112
- @user1.votes.up.by_type(Post)
114
+ @user1.votes.up.for_type(Post)
113
115
  ```
114
116
 
115
117
  Once scoping is complete, you can also trigger a get for the
@@ -137,7 +139,7 @@ Unvoting works for both positive and negative votes.
137
139
 
138
140
  ### Examples with scopes
139
141
 
140
- You can add an scope to your vote
142
+ You can add a scope to your vote
141
143
 
142
144
  ```ruby
143
145
  # positive votes
@@ -215,9 +217,9 @@ check how the voter voted by using ``voted_as_when_voted_for``.
215
217
  @user.voted_for? @comment2 # => true
216
218
  @user.voted_for? @comment3 # => false
217
219
 
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
220
+ @user.voted_as_when_voted_for @comment1 # => true, user liked it
221
+ @user.voted_as_when_voted_for @comment2 # => false, user didnt like it
222
+ @user.voted_as_when_voted_for @comment3 # => nil, user has yet to vote
221
223
  ```
222
224
 
223
225
  You can also check whether the voter has voted up or down.
@@ -317,12 +319,14 @@ class AddCachedVotesToPosts < ActiveRecord::Migration
317
319
  add_column :posts, :cached_votes_down, :integer, :default => 0
318
320
  add_column :posts, :cached_weighted_score, :integer, :default => 0
319
321
  add_column :posts, :cached_weighted_total, :integer, :default => 0
322
+ add_column :posts, :cached_weighted_average, :float, :default => 0.0
320
323
  add_index :posts, :cached_votes_total
321
324
  add_index :posts, :cached_votes_score
322
325
  add_index :posts, :cached_votes_up
323
326
  add_index :posts, :cached_votes_down
324
327
  add_index :posts, :cached_weighted_score
325
328
  add_index :posts, :cached_weighted_total
329
+ add_index :posts, :cached_weighted_average
326
330
 
327
331
  # Uncomment this line to force caching of existing votes
328
332
  # Post.find_each(&:update_cached_votes)
@@ -335,10 +339,74 @@ class AddCachedVotesToPosts < ActiveRecord::Migration
335
339
  remove_column :posts, :cached_votes_down
336
340
  remove_column :posts, :cached_weighted_score
337
341
  remove_column :posts, :cached_weighted_total
342
+ remove_column :posts, :cached_weighted_average
338
343
  end
339
344
  end
340
345
  ```
341
346
 
347
+ If you have a scope for your vote, let's say `subscribe`, your migration will be slightly different like below:
348
+
349
+ ```ruby
350
+ class AddCachedVotesToPosts < ActiveRecord::Migration
351
+ def self.up
352
+ add_column :posts, :cached_scoped_subscribe_votes_total, :integer, :default => 0
353
+ add_column :posts, :cached_scoped_subscribe_votes_score, :integer, :default => 0
354
+ add_column :posts, :cached_scoped_subscribe_votes_up, :integer, :default => 0
355
+ add_column :posts, :cached_scoped_subscribe_votes_down, :integer, :default => 0
356
+ add_column :posts, :cached_weighted_subscribe_score, :integer, :default => 0
357
+ add_column :posts, :cached_weighted_subscribe_total, :integer, :default => 0
358
+ add_column :posts, :cached_weighted_subscribe_average, :float, :default => 0.0
359
+ add_index :posts, :cached_scoped_subscribe_votes_total
360
+ add_index :posts, :cached_scoped_subscribe_votes_score
361
+ add_index :posts, :cached_scoped_subscribe_votes_up
362
+ add_index :posts, :cached_scoped_subscribe_votes_down
363
+ add_index :posts, :cached_weighted_subscribe_score
364
+ add_index :posts, :cached_weighted_subscribe_total
365
+ add_index :posts, :cached_weighted_subscribe_average
366
+ end
367
+
368
+ def self.down
369
+ remove_column :posts, :cached_scoped_subscribe_votes_total
370
+ remove_column :posts, :cached_scoped_subscribe_votes_score
371
+ remove_column :posts, :cached_scoped_subscribe_votes_up
372
+ remove_column :posts, :cached_scoped_subscribe_votes_down
373
+ remove_column :posts, :cached_weighted_subscribe_score
374
+ remove_column :posts, :cached_weighted_subscribe_total
375
+ remove_column :posts, :cached_weighted_subscribe_average
376
+ end
377
+ end
378
+ ```
379
+
380
+ `cached_weighted_average` can be helpful for a rating system, e.g.:
381
+
382
+ Order by average rating:
383
+
384
+ ```ruby
385
+ Post.order(:cached_weighted_average => :desc)
386
+ ```
387
+
388
+ Display average rating:
389
+
390
+ ```erb
391
+ <%= post.weighted_average.round(2) %> / 5
392
+ <!-- 3.5 / 5 -->
393
+ ```
394
+ ## updated_at at Votable model
395
+
396
+ You can control whether `updated_at` column of votable model will be touched or
397
+ not by passing `cacheable_strategy` option to `acts_as_votable` method.
398
+
399
+ By default, `update_attributes` strategy is used. Pass `:update_columns` as
400
+ `cacheable_strategy` if you don't want to touch model's `updated_at` column.
401
+ ```ruby
402
+ class Post < ActiveRecord::Base
403
+ acts_as_votable cacheable_strategy: :update_columns
404
+ end
405
+ ```
406
+
407
+ NOTE: this option does not work for ActiveRecord < 3.1
408
+
409
+
342
410
  ## Testing
343
411
 
344
412
  All tests follow the RSpec format and are located in the spec directory.
@@ -352,7 +420,7 @@ rake spec
352
420
 
353
421
  ### Fixes for votable voter model
354
422
 
355
- In version 0.8.0, there is bugs for a model that is both votable and voter.
423
+ In version 0.8.0, there are bugs for a model that is both votable and voter.
356
424
  Some name-conflicting methods are renamed:
357
425
  + Renamed Votable.votes to votes_for
358
426
  + Renamed Votable.vote to vote_by,
@@ -370,7 +438,7 @@ Some name-conflicting methods are renamed:
370
438
  Acts as votable is released under the [MIT
371
439
  License](http://www.opensource.org/licenses/MIT).
372
440
 
373
- ## TODO
441
+ ## Next steps
374
442
 
375
443
  - Pass in a block of options when creating acts_as. Allow for things
376
444
  like disabling the aliasing
@@ -379,8 +447,7 @@ License](http://www.opensource.org/licenses/MIT).
379
447
  that the user likes, while `@user.likes @model` will cast a vote for @model by
380
448
  @user.
381
449
 
382
-
383
450
  - 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.
451
+ 'true/false'. Need to come up with guidelines for naming these methods.
385
452
 
386
453
  - Create more aliases. Specifically for counting votes and finding votes.
data/Rakefile CHANGED
@@ -1,10 +1,12 @@
1
- require 'bundler'
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler"
2
4
  Bundler::GemHelper.install_tasks
3
5
 
4
- require 'rspec/core/rake_task'
6
+ require "rspec/core/rake_task"
5
7
 
6
8
  desc "Run specs"
7
9
  RSpec::Core::RakeTask.new(:spec)
8
10
 
9
- desc 'Default: run specs.'
10
- task :default => :spec
11
+ desc "Default: run specs."
12
+ task default: :spec
@@ -1,4 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
2
4
  $:.push File.expand_path("../lib", __FILE__)
3
5
  require "acts_as_votable/version"
4
6
 
@@ -9,16 +11,21 @@ Gem::Specification.new do |s|
9
11
  s.authors = ["Ryan"]
10
12
  s.email = ["ryanto"]
11
13
  s.homepage = "http://rubygems.org/gems/acts_as_votable"
12
- s.summary = %q{Rails gem to allowing records to be votable}
13
- s.description = %q{Rails gem to allowing records to be votable}
14
+ s.summary = "Rails gem to allowing records to be votable"
15
+ s.description = "Rails gem to allowing records to be votable"
16
+ s.license = "MIT"
14
17
 
15
18
  s.rubyforge_project = "acts_as_votable"
16
19
 
17
20
  s.files = `git ls-files`.split("\n")
18
21
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
20
23
  s.require_paths = ["lib"]
21
24
 
22
- s.add_development_dependency "rspec"
23
- s.add_development_dependency "sqlite3", '1.3.7'
25
+ s.add_development_dependency "rspec", "~> 3.6"
26
+ s.add_development_dependency "sqlite3", "~> 1.3"
27
+ s.add_development_dependency "rubocop", "~> 0.49.1"
28
+ s.add_development_dependency "simplecov", "~> 0.15.0"
29
+ s.add_development_dependency "appraisal", "~> 2.2"
30
+ s.add_development_dependency "factory_girl", "~> 4.8"
24
31
  end