recommendable 1.1.3 → 1.1.4
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/Gemfile.lock +3 -3
- data/app/workers/recommendable/sidekiq_worker.rb +1 -1
- data/lib/generators/recommendable/templates/initializer.rb +15 -0
- data/lib/recommendable.rb +2 -0
- data/lib/recommendable/acts_as_recommendable.rb +24 -0
- data/lib/recommendable/acts_as_recommended_to.rb +5 -1
- data/lib/recommendable/version.rb +1 -1
- data/lib/sidekiq/middleware/client/unique_jobs.rb +37 -0
- data/lib/sidekiq/middleware/server/unique_jobs.rb +17 -0
- data/lib/tasks/recommendable_tasks.rake +1 -1
- data/spec/models/dislike_spec.rb +14 -0
- data/spec/models/like_spec.rb +14 -0
- metadata +5 -3
data/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
recommendable (1.1.
|
4
|
+
recommendable (1.1.3)
|
5
5
|
hooks
|
6
6
|
rails (>= 3.0.0)
|
7
|
-
redis (
|
7
|
+
redis (>= 2.2.0)
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: http://rubygems.org/
|
@@ -79,7 +79,7 @@ GEM
|
|
79
79
|
rake (0.9.2.2)
|
80
80
|
rdoc (3.12)
|
81
81
|
json (~> 1.4)
|
82
|
-
redis (
|
82
|
+
redis (3.0.1)
|
83
83
|
shoulda (3.0.1)
|
84
84
|
shoulda-context (~> 1.0.0)
|
85
85
|
shoulda-matchers (~> 1.0.0)
|
@@ -2,7 +2,7 @@ module Recommendable
|
|
2
2
|
if defined?(Sidekiq)
|
3
3
|
class SidekiqWorker
|
4
4
|
include ::Sidekiq::Worker
|
5
|
-
sidekiq_options :queue => :recommendable
|
5
|
+
sidekiq_options :queue => :recommendable, :unique => true
|
6
6
|
|
7
7
|
def perform(user_id)
|
8
8
|
user = Recommendable.user_class.find(user_id)
|
@@ -11,3 +11,18 @@ require "redis"
|
|
11
11
|
# Tell Redis which database to use (usually between 0 and 15). The default of 0
|
12
12
|
# is most likely okay unless you have another application using that database.
|
13
13
|
# Recommendable.redis.select "0"
|
14
|
+
|
15
|
+
# If using Sidekiq, uncomment the following or place it in config/initializers/sidekiq.rb:
|
16
|
+
# Sidekiq.configure_server do |config|
|
17
|
+
# require 'sidekiq/middleware/server/unique_jobs'
|
18
|
+
# config.server_middleware do |chain|
|
19
|
+
# chain.add Sidekiq::Middleware::Server::UniqueJobs
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# Sidekiq.configure_client do |config|
|
24
|
+
# require 'sidekiq/middleware/client/unique_jobs'
|
25
|
+
# config.client_middleware do |chain|
|
26
|
+
# chain.add Sidekiq::Middleware::Client::UniqueJobs
|
27
|
+
# end
|
28
|
+
# end
|
data/lib/recommendable.rb
CHANGED
@@ -6,6 +6,8 @@ require 'recommendable/exceptions'
|
|
6
6
|
require 'recommendable/railtie' if defined?(Rails)
|
7
7
|
require 'recommendable/version'
|
8
8
|
require 'hooks'
|
9
|
+
require 'sidekiq/middleware/client/unique_jobs' if defined?(Sidekiq)
|
10
|
+
require 'sidekiq/middleware/server/unique_jobs' if defined?(Sidekiq)
|
9
11
|
|
10
12
|
module Recommendable
|
11
13
|
mattr_accessor :redis, :user_class
|
@@ -121,8 +121,20 @@ module Recommendable
|
|
121
121
|
protected :redis_key
|
122
122
|
|
123
123
|
module LikeableMethods
|
124
|
+
# Retrieve the number of likes this object has received. Cached in Redis.
|
125
|
+
# @return [Fixnum] the number of times this object has been liked
|
126
|
+
def like_count
|
127
|
+
Recommendable.redis.get("#{redis_key}:like_count").to_i
|
128
|
+
end
|
129
|
+
|
124
130
|
private
|
125
131
|
|
132
|
+
# Updates the cache for how many times this object has been liked.
|
133
|
+
# @private
|
134
|
+
def update_like_count
|
135
|
+
Recommendable.redis.set "#{redis_key}:like_count", liked_by.count
|
136
|
+
end
|
137
|
+
|
126
138
|
# Used for setup purposes. Creates a set in redis containing users that
|
127
139
|
# have liked this object.
|
128
140
|
# @private
|
@@ -135,8 +147,20 @@ module Recommendable
|
|
135
147
|
end
|
136
148
|
|
137
149
|
module DislikeableMethods
|
150
|
+
# Retrieve the number of dislikes this object has received. Cached in Redis.
|
151
|
+
# @return [Fixnum] the number of times this object has been disliked
|
152
|
+
def dislike_count
|
153
|
+
Recommendable.redis.get("#{redis_key}:dislike_count").to_i
|
154
|
+
end
|
155
|
+
|
138
156
|
private
|
139
157
|
|
158
|
+
# Updates the cache for how many times this object has been disliked.
|
159
|
+
# @private
|
160
|
+
def update_dislike_count
|
161
|
+
Recommendable.redis.set "#{redis_key}:dislike_count", disliked_by.count
|
162
|
+
end
|
163
|
+
|
140
164
|
# Used for setup purposes. Creates a set in redis containing users that
|
141
165
|
# have disliked this object.
|
142
166
|
# @private
|
@@ -52,7 +52,11 @@ module Recommendable
|
|
52
52
|
end
|
53
53
|
|
54
54
|
%w(like unlike dislike undislike).each do |action|
|
55
|
-
send "after_#{action}", lambda { |obj|
|
55
|
+
send "after_#{action}", lambda { |obj|
|
56
|
+
obj.send(:update_score)
|
57
|
+
obj.send "update_#{action.gsub('un', '')}_count"
|
58
|
+
Recommendable.enqueue(self.id)
|
59
|
+
}
|
56
60
|
end
|
57
61
|
|
58
62
|
before_stash { |obj| unignore(obj) and unpredict(obj) }
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
if defined?(Sidekiq)
|
4
|
+
module Sidekiq
|
5
|
+
module Middleware
|
6
|
+
module Client
|
7
|
+
class UniqueJobs
|
8
|
+
HASH_KEY_EXPIRATION = 30 * 60
|
9
|
+
|
10
|
+
def call(worker_class, item, queue)
|
11
|
+
enabled = worker_class.get_sidekiq_options['unique']
|
12
|
+
if enabled
|
13
|
+
payload_hash = Digest::MD5.hexdigest(Sidekiq.dump_json(item))
|
14
|
+
unique = false
|
15
|
+
|
16
|
+
Sidekiq.redis do |conn|
|
17
|
+
conn.watch(payload_hash)
|
18
|
+
|
19
|
+
if conn.get(payload_hash)
|
20
|
+
conn.unwatch
|
21
|
+
else
|
22
|
+
unique = conn.multi do
|
23
|
+
conn.setex(payload_hash, HASH_KEY_EXPIRATION, 1)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
yield if unique
|
28
|
+
else
|
29
|
+
yield
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
if defined?(Sidekiq)
|
2
|
+
module Sidekiq
|
3
|
+
module Middleware
|
4
|
+
module Server
|
5
|
+
class UniqueJobs
|
6
|
+
def call(*args)
|
7
|
+
yield
|
8
|
+
ensure
|
9
|
+
json = Sidekiq.dump_json(args[1])
|
10
|
+
hash = Digest::MD5.hexdigest(json)
|
11
|
+
Sidekiq.redis {|conn| conn.del(hash) }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
require 'resque/tasks'
|
1
|
+
require 'resque/tasks' if defined?(Resque)
|
data/spec/models/dislike_spec.rb
CHANGED
@@ -23,5 +23,19 @@ class DislikeSpec < MiniTest::Spec
|
|
23
23
|
@user.dislike(movie).must_be_nil
|
24
24
|
Recommendable::Dislike.count.must_equal 1
|
25
25
|
end
|
26
|
+
|
27
|
+
it "should cache the number of dislikes" do
|
28
|
+
movie = Movie.create(:title => "Star Wars: Episode I - The Phantom Menace", :year => 1999)
|
29
|
+
@user2 = User.create(:username => "frank")
|
30
|
+
|
31
|
+
@user.dislike(movie)
|
32
|
+
movie.dislike_count.must_equal 1
|
33
|
+
|
34
|
+
@user2.dislike(movie)
|
35
|
+
movie.dislike_count.must_equal 2
|
36
|
+
|
37
|
+
@user.undislike(movie)
|
38
|
+
movie.dislike_count.must_equal 1
|
39
|
+
end
|
26
40
|
end
|
27
41
|
end
|
data/spec/models/like_spec.rb
CHANGED
@@ -24,5 +24,19 @@ class LikeSpec < MiniTest::Spec
|
|
24
24
|
@user.like(movie).must_be_nil
|
25
25
|
Recommendable::Like.count.must_equal 1
|
26
26
|
end
|
27
|
+
|
28
|
+
it "should cache the number of likes" do
|
29
|
+
movie = Movie.create(:title => "2001: A Space Odyssey", :year => 1968)
|
30
|
+
@user2 = User.create(:username => "frank")
|
31
|
+
|
32
|
+
@user.like(movie)
|
33
|
+
movie.like_count.must_equal 1
|
34
|
+
|
35
|
+
@user2.like(movie)
|
36
|
+
movie.like_count.must_equal 2
|
37
|
+
|
38
|
+
@user.unlike(movie)
|
39
|
+
movie.like_count.must_equal 1
|
40
|
+
end
|
27
41
|
end
|
28
42
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: recommendable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sqlite3
|
@@ -195,6 +195,8 @@ files:
|
|
195
195
|
- lib/recommendable/helpers.rb
|
196
196
|
- lib/recommendable/railtie.rb
|
197
197
|
- lib/recommendable/version.rb
|
198
|
+
- lib/sidekiq/middleware/client/unique_jobs.rb
|
199
|
+
- lib/sidekiq/middleware/server/unique_jobs.rb
|
198
200
|
- lib/tasks/recommendable_tasks.rake
|
199
201
|
- recommendable.gemspec
|
200
202
|
- script/rails
|
@@ -276,7 +278,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
276
278
|
version: '0'
|
277
279
|
requirements: []
|
278
280
|
rubyforge_project:
|
279
|
-
rubygems_version: 1.8.
|
281
|
+
rubygems_version: 1.8.23
|
280
282
|
signing_key:
|
281
283
|
specification_version: 3
|
282
284
|
summary: Add like-based and/or dislike-based recommendations to your app.
|