likeable 0.0.1
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/.autotest +1 -0
- data/.rspec +2 -0
- data/.rvmrc +19 -0
- data/Gemfile +18 -0
- data/README.md +108 -0
- data/Rakefile +26 -0
- data/VERSION +1 -0
- data/autotest/discover.rb +1 -0
- data/lib/.DS_Store +0 -0
- data/lib/likeable.rb +115 -0
- data/lib/likeable/facepile.rb +27 -0
- data/lib/likeable/like.rb +31 -0
- data/lib/likeable/module_methods.rb +133 -0
- data/lib/likeable/user_methods.rb +36 -0
- data/license.txt +22 -0
- data/likeable.gemspec +94 -0
- data/spec/likeable/facepile_spec.rb +56 -0
- data/spec/likeable/like_spec.rb +19 -0
- data/spec/likeable/module_methods_spec.rb +63 -0
- data/spec/likeable/setup_spec.rb +66 -0
- data/spec/likeable/user_methods_spec.rb +68 -0
- data/spec/likeable_spec.rb +103 -0
- data/spec/spec_helper.rb +44 -0
- metadata +226 -0
data/.autotest
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'autotest/growl'
|
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
ruby_string="ree"
|
4
|
+
gemset_name="likeable"
|
5
|
+
|
6
|
+
if rvm list strings | grep -q "${ruby_string}" ; then
|
7
|
+
|
8
|
+
rvm use "${ruby_string}@${gemset_name}" --create
|
9
|
+
|
10
|
+
# Complain if bundler isn't installed
|
11
|
+
if [[ -z "`gem which bundler 2>&1 | grep -v ERROR`" ]]; then
|
12
|
+
echo "You need bundler:"
|
13
|
+
echo ""
|
14
|
+
echo " gem install bundler"
|
15
|
+
echo ""
|
16
|
+
fi
|
17
|
+
else
|
18
|
+
echo "${ruby_string} was not found, please run 'rvm install ${ruby_string}' and then cd back into the project directory."
|
19
|
+
fi
|
data/Gemfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
gem 'activesupport'
|
3
|
+
gem 'keytar', '>=1.5.2'
|
4
|
+
gem 'redis'
|
5
|
+
|
6
|
+
|
7
|
+
group :development, :test do
|
8
|
+
gem 'activerecord', '~>3.0.4' ## not needed if you're just using KeyBuilder
|
9
|
+
gem 'rake', '~>0.8.7'
|
10
|
+
gem 'jeweler', '~>1.5.2'
|
11
|
+
gem "autotest-standalone"
|
12
|
+
gem "autotest-growl"
|
13
|
+
end
|
14
|
+
|
15
|
+
group :test do
|
16
|
+
gem 'sqlite3', '~> 1.3.3'
|
17
|
+
gem 'rspec', '~> 2.5'
|
18
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
Use Redis to Make your Ruby objects Likeable!
|
2
|
+
======
|
3
|
+
|
4
|
+
You like this
|
5
|
+
-------------
|
6
|
+
Likeable is the easiest way to allow your models to be liked by users, just drop a few lines of code into your model and you're good to go.
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
|
10
|
+
class Comment
|
11
|
+
include Likeable
|
12
|
+
|
13
|
+
# ...
|
14
|
+
end
|
15
|
+
|
16
|
+
class User
|
17
|
+
include Likeable::UserMethods
|
18
|
+
|
19
|
+
# ...
|
20
|
+
end
|
21
|
+
|
22
|
+
Likeable.setup do |likeable|
|
23
|
+
likeable.redis = Redis.new
|
24
|
+
end
|
25
|
+
|
26
|
+
comment = Comment.find(15)
|
27
|
+
comment.like_count # => 0
|
28
|
+
current_user.like!(comment) # => #<Likeable::Like ... >
|
29
|
+
comment.like_count # => 1
|
30
|
+
comment.likes # => [#<Likeable::Like ... >]
|
31
|
+
comment.likes.last.user # => #<User ... >
|
32
|
+
comment.likes.last.created_at # => Wed Jul 27 19:34:32 -0500 2011
|
33
|
+
|
34
|
+
comment.liked_by?(current_user) # => true
|
35
|
+
|
36
|
+
current_user.all_liked(Comment) # => [#<Comment ...>, ...]
|
37
|
+
```
|
38
|
+
|
39
|
+
|
40
|
+
Setup
|
41
|
+
=======
|
42
|
+
Gemfile:
|
43
|
+
|
44
|
+
gem 'Likeable'
|
45
|
+
|
46
|
+
Next set up your Redis connection in initializers/likeable.rb:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
|
50
|
+
Likeable.setup do |likeable|
|
51
|
+
likeable.redis = Redis.new
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
Then add the `Likeable::UserMethods` module to models/user.rb:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
|
59
|
+
class User
|
60
|
+
include Likeable::UserMethods
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
Finally add `Likeable` module to any model you want to be liked:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
|
68
|
+
class Comment
|
69
|
+
include Likeable
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
|
74
|
+
Thats about it.
|
75
|
+
|
76
|
+
RedisRed RedisRedi
|
77
|
+
RedisRedisRedi RedisRedisRedisR
|
78
|
+
RedisRedisRedisRedi RedisRedisRedisRedi
|
79
|
+
RedisRedisRedisRedisRedisRedisRe Redi
|
80
|
+
RedisRedisRedisRedisRedisRedisRe Redi
|
81
|
+
RedisRedisRedisRedisRedisRedisRedisR Redi
|
82
|
+
RedisRedisRedisRedisRedisRedisRedisRedis R
|
83
|
+
RedisRedisRedisRedisRedisRedisRedisRedisRedi Red
|
84
|
+
RedisRedisRedisRedisRedisRedisRedisRedisRedisRe R
|
85
|
+
RedisRedisRedisRedisRedisRedisRedisRedisRedisRedi
|
86
|
+
RedisRedisRedisRedisRedisRedisRedisRedisRedisRedi
|
87
|
+
RedisRedisRedisRedisRedisRedisRedisRedisRedisRe
|
88
|
+
RedisRedisRedisRedisRedisRedisRedisRedisRedis
|
89
|
+
RedisRedisRedisRedisRedisRedisRedisRedisRe
|
90
|
+
RedisRedisRedisRedisRedisRedisRedisRe
|
91
|
+
RedisRedisRedisRedisRedisRedisR
|
92
|
+
RedisRedisRedisRedisRedis
|
93
|
+
RedisRedisRedisRedis
|
94
|
+
RedisRedisRed
|
95
|
+
RedisRedi
|
96
|
+
RedisR
|
97
|
+
Redi
|
98
|
+
Re
|
99
|
+
|
100
|
+
Contribution
|
101
|
+
============
|
102
|
+
|
103
|
+
Fork away. If you want to chat about a feature idea, or a question you can find me on the twitters [@schneems](http://twitter.com/schneems). Put any major changes into feature branches. Make sure all tests stay green, and make sure your changes are covered.
|
104
|
+
|
105
|
+
|
106
|
+
licensed under MIT License
|
107
|
+
Copyright (c) 2011 Schneems. See LICENSE.txt for
|
108
|
+
further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "likeable"
|
16
|
+
gem.homepage = "http://github.com/Schnems/likeable"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Like ruby objects backed by redis}
|
19
|
+
gem.description = %Q{
|
20
|
+
Likeable allows you to make your models...well...likeable using redis.
|
21
|
+
}
|
22
|
+
gem.email = "richard.schneeman@gmail.com"
|
23
|
+
gem.authors = ["Schneems"]
|
24
|
+
gem.add_development_dependency "rspec"
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
data/lib/.DS_Store
ADDED
Binary file
|
data/lib/likeable.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'keytar'
|
3
|
+
|
4
|
+
|
5
|
+
module Likeable
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
include Keytar
|
10
|
+
include Likeable::Facepile
|
11
|
+
define_key :like, :key_case => nil
|
12
|
+
|
13
|
+
if self.respond_to?(:after_destroy)
|
14
|
+
after_destroy :destroy_all_likes
|
15
|
+
else
|
16
|
+
warn "#{self} doesn't support after_destroy callback, likes will not be cleared automatically when object is destroyed"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def destroy_all_likes
|
21
|
+
liked_users.each {|user| self.remove_like_from(user) }
|
22
|
+
end
|
23
|
+
|
24
|
+
# create a like
|
25
|
+
# the user who created the like has a reference to the object liked
|
26
|
+
def add_like_from(user, time = Time.now.to_f)
|
27
|
+
Likeable.redis.hset(like_key, user.id, time)
|
28
|
+
Likeable.redis.hset(user.like_key(self.class.to_s.downcase), self.id, time)
|
29
|
+
like = Like.new(:target => self, :user => user, :time => time)
|
30
|
+
after_like(like)
|
31
|
+
clear_memoized_methods(:like_count, :like_user_ids, :liked_user_ids, :liked_users, :likes)
|
32
|
+
like
|
33
|
+
end
|
34
|
+
|
35
|
+
def clear_memoized_methods(*methods)
|
36
|
+
methods.each do |method|
|
37
|
+
eval("@#{method} = nil")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def after_like(like)
|
42
|
+
Likeable.after_like.call(like)
|
43
|
+
end
|
44
|
+
|
45
|
+
# removes a like
|
46
|
+
def remove_like_from(user)
|
47
|
+
Likeable.redis.hdel(like_key, user.id)
|
48
|
+
Likeable.redis.hdel(user.like_key(self.class.to_s.downcase), self.id)
|
49
|
+
clear_memoized_methods(:like_count, :like_user_ids, :liked_user_ids, :liked_users)
|
50
|
+
end
|
51
|
+
|
52
|
+
def like_count
|
53
|
+
@like_count ||= @like_user_ids.try(:count) || @likes.try(:count) || Likeable.redis.hlen(like_key)
|
54
|
+
end
|
55
|
+
|
56
|
+
# get all user ids that have liked a target object
|
57
|
+
def like_user_ids
|
58
|
+
@like_user_ids ||= (Likeable.redis.hkeys(like_key)||[]).map(&:to_i)
|
59
|
+
end
|
60
|
+
|
61
|
+
def liked_users(limit = nil)
|
62
|
+
@liked_users ||= User.where(:id => like_user_ids)
|
63
|
+
end
|
64
|
+
|
65
|
+
def likes
|
66
|
+
@likes ||= begin
|
67
|
+
Likeable.redis.hgetall(like_key).collect do |user_id, time|
|
68
|
+
Like.new(:user_id => user_id, :time => time, :target => self)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# did given user like the object
|
74
|
+
def liked_by?(user)
|
75
|
+
return false unless user
|
76
|
+
liked_by = @like_user_ids.include?(user.id) if @like_user_ids
|
77
|
+
liked_by ||= Likeable.redis.hexists(like_key, user.id)
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
def likeable_resource_name
|
82
|
+
Likeable.get_resource_name_for_class(self.class)
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
### Class Methods ###
|
87
|
+
# ----------------- #
|
88
|
+
# allows us to setup callbacks when creating likes
|
89
|
+
# after_like :notify_users
|
90
|
+
module ClassMethods
|
91
|
+
|
92
|
+
def all_liked_ids_by(user)
|
93
|
+
key = user.like_key(self.to_s.downcase)
|
94
|
+
ids = (Likeable.redis.hkeys(key)||[]).map(&:to_i)
|
95
|
+
end
|
96
|
+
|
97
|
+
def all_liked_by(user)
|
98
|
+
ids = all_liked_ids_by(user)
|
99
|
+
self.where(:id => ids)
|
100
|
+
end
|
101
|
+
|
102
|
+
def after_like(*methods)
|
103
|
+
define_method(:after_like) do |like|
|
104
|
+
methods.each do |method|
|
105
|
+
eval("#{method}(like)")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
require 'likeable/like'
|
113
|
+
require 'likeable/facepile'
|
114
|
+
require 'likeable/user_methods'
|
115
|
+
require 'likeable/module_methods'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Likeable
|
2
|
+
module Facepile
|
3
|
+
# returns friend of user who like target
|
4
|
+
def liked_friends(user, limit = nil)
|
5
|
+
friend_ids = liked_friend_ids(user)
|
6
|
+
friend_ids = friend_ids.sample(limit) unless limit.blank?
|
7
|
+
@liked_friends ||= Likeable.find_many(User, friend_ids)
|
8
|
+
end
|
9
|
+
|
10
|
+
def liked_friend_ids(user)
|
11
|
+
@liked_friend_ids ||= like_user_ids & user.friend_ids
|
12
|
+
end
|
13
|
+
|
14
|
+
def ids_for_facepile(user, limit = Likeable.facepile_default_limit)
|
15
|
+
ids = liked_friend_ids(user).shuffle + like_user_ids.shuffle # show friends first
|
16
|
+
ids.uniq.first(limit)
|
17
|
+
end
|
18
|
+
|
19
|
+
def users_for_facepile(user, limit = Likeable.facepile_default_limit)
|
20
|
+
return [] if user.blank?
|
21
|
+
@facepile ||= begin
|
22
|
+
return nil unless ids = ids_for_facepile(user, limit)
|
23
|
+
Likeable.find_many(User, ids)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
class Likeable::Like
|
4
|
+
attr_accessor :created_at, :target, :like_user, :user_id
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
self.created_at = Time.at(options[:time].try(:to_f)||Time.now)
|
8
|
+
self.target = options[:target]
|
9
|
+
self.user_id = options[:user].try(:id) || options[:user_id]
|
10
|
+
self.like_user = options[:user]
|
11
|
+
end
|
12
|
+
|
13
|
+
def id
|
14
|
+
Digest::SHA1.hexdigest("#{user_id}#{target.class}#{target.id}#{created_at}")
|
15
|
+
end
|
16
|
+
|
17
|
+
def user
|
18
|
+
@user ||= like_user
|
19
|
+
@user ||= Likeable.find_one(User, user_id)
|
20
|
+
@user
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_hash(type=:full)
|
24
|
+
{
|
25
|
+
:created_at => created_at.iso8601,
|
26
|
+
:type => target.class.name.gsub(/^[A-Za-z]+::/, '').underscore.downcase.to_sym,
|
27
|
+
:target => target.to_hash(type),
|
28
|
+
:user => user.to_hash(type)
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'redis'
|
2
|
+
|
3
|
+
module Likeable
|
4
|
+
mattr_accessor :facepile_default_limit
|
5
|
+
self.facepile_default_limit = 9
|
6
|
+
|
7
|
+
|
8
|
+
### Module Methods ###
|
9
|
+
# ------------------ #
|
10
|
+
class << self
|
11
|
+
def classes
|
12
|
+
(@classes||[]).flatten
|
13
|
+
end
|
14
|
+
|
15
|
+
def classes=(*args)
|
16
|
+
@classes = args
|
17
|
+
end
|
18
|
+
|
19
|
+
# Likeable.model("Highlight")
|
20
|
+
# ------------------------- #
|
21
|
+
# turns a string into a model
|
22
|
+
# "Highlight".constantize # => Highlight; "Hi1i6ht".constantize = #=> false
|
23
|
+
def model(target_model)
|
24
|
+
target_model.camelcase.constantize
|
25
|
+
rescue NameError => ex
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
|
29
|
+
# Likeable.find_by_resource_id("highlight", 22)
|
30
|
+
# ---------------------------------------- #
|
31
|
+
# #<Highlight id: ... # if highlight 22 exists
|
32
|
+
# nil # if highlight 22 does not exist
|
33
|
+
def find_by_resource_id(resource_name, target_id)
|
34
|
+
target = Likeable.get_class_for_resource_name(resource_name)
|
35
|
+
if target.present?
|
36
|
+
Likeable.find_one(target, target_id)
|
37
|
+
else
|
38
|
+
false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Likeable.get_class_for_resource_name('photo')
|
43
|
+
# ------------------------- #
|
44
|
+
# Returns the class for the resource name
|
45
|
+
def get_class_for_resource_name(resource_name)
|
46
|
+
self.model(resource_name)
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_resource_name_for_class(klass)
|
50
|
+
klass
|
51
|
+
end
|
52
|
+
|
53
|
+
def redis
|
54
|
+
@redis ||= Redis.new
|
55
|
+
end
|
56
|
+
|
57
|
+
def redis=(redis)
|
58
|
+
@redis = redis
|
59
|
+
end
|
60
|
+
|
61
|
+
def after_like(&block)
|
62
|
+
@after_like = block if block.present?
|
63
|
+
@after_like ||= lambda {}
|
64
|
+
@after_like
|
65
|
+
end
|
66
|
+
|
67
|
+
def find_many=(find_many)
|
68
|
+
@find_many = find_many
|
69
|
+
end
|
70
|
+
|
71
|
+
def find_many(klass, ids)
|
72
|
+
@find_many ||= lambda {|klass, ids| klass.where(:id => ids)}
|
73
|
+
@find_many.call(klass, ids)
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def find_one(klass, id)
|
78
|
+
@find_one ||= lambda {|klass, ids| klass.where(:id => id)}
|
79
|
+
@find_one.call(klass, id)
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_one=(find_one)
|
83
|
+
@find_one = find_one
|
84
|
+
end
|
85
|
+
|
86
|
+
def user_class
|
87
|
+
@user_class ||= ::User
|
88
|
+
end
|
89
|
+
|
90
|
+
def user_class=(user)
|
91
|
+
raise "User must be a class #{user.inspect}" unless user.class == Class
|
92
|
+
@user_class = user
|
93
|
+
end
|
94
|
+
|
95
|
+
# Likeable.setup do |like|
|
96
|
+
# like.redis = Redis.new(#...)
|
97
|
+
# like.find_one = lambda {|klass, id | klass.where(:id => id)}
|
98
|
+
# like.find_many = lambda {|klass, ids| klass.where(:id => ids)}
|
99
|
+
# like.classes = Spot, Comment
|
100
|
+
# end
|
101
|
+
|
102
|
+
|
103
|
+
def include_in_class(klass, include_item)
|
104
|
+
case
|
105
|
+
when defined?(Rails::Application)
|
106
|
+
Rails::Application.class_eval do
|
107
|
+
config.to_prepare do
|
108
|
+
klass.send :include, include_item
|
109
|
+
end
|
110
|
+
end
|
111
|
+
else
|
112
|
+
klass.send :include, include_item
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def make_classes_likeable
|
117
|
+
classes.each do |klass|
|
118
|
+
include_in_class(klass, Likeable)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def give_users_like_ability
|
123
|
+
include_in_class user_class, ::Likeable::UserMethods
|
124
|
+
end
|
125
|
+
|
126
|
+
def setup(&block)
|
127
|
+
yield self unless block.blank?
|
128
|
+
make_classes_likeable
|
129
|
+
give_users_like_ability
|
130
|
+
true
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Likeable::UserMethods
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
include Keytar
|
6
|
+
define_key :like, :key_case => nil
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
def like!(obj)
|
11
|
+
obj.add_like_from(self)
|
12
|
+
end
|
13
|
+
|
14
|
+
def unlike!(obj)
|
15
|
+
obj.remove_like_from(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def like?(obj)
|
19
|
+
obj.liked_by?(self)
|
20
|
+
end
|
21
|
+
alias :likes? :like?
|
22
|
+
|
23
|
+
def friend_ids_that_like(obj)
|
24
|
+
obj.liked_friend_ids(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def friends_that_like(obj, limit = nil)
|
28
|
+
obj.liked_friends(self, limit)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @user.liked(Spot)
|
32
|
+
# will return all spots that user has liked
|
33
|
+
def all_liked(klass)
|
34
|
+
klass.all_liked_by(self)
|
35
|
+
end
|
36
|
+
end
|
data/license.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
licensed under MIT License:
|
2
|
+
|
3
|
+
Copyright (c) 2011 Schneems
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/likeable.gemspec
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "likeable"
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Schneems"]
|
12
|
+
s.date = "2011-10-12"
|
13
|
+
s.description = "\n Likeable allows you to make your models...well...likeable using redis.\n "
|
14
|
+
s.email = "richard.schneeman@gmail.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".autotest",
|
20
|
+
".rspec",
|
21
|
+
".rvmrc",
|
22
|
+
"Gemfile",
|
23
|
+
"README.md",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"autotest/discover.rb",
|
27
|
+
"lib/.DS_Store",
|
28
|
+
"lib/likeable.rb",
|
29
|
+
"lib/likeable/facepile.rb",
|
30
|
+
"lib/likeable/like.rb",
|
31
|
+
"lib/likeable/module_methods.rb",
|
32
|
+
"lib/likeable/user_methods.rb",
|
33
|
+
"license.txt",
|
34
|
+
"likeable.gemspec",
|
35
|
+
"spec/likeable/facepile_spec.rb",
|
36
|
+
"spec/likeable/like_spec.rb",
|
37
|
+
"spec/likeable/module_methods_spec.rb",
|
38
|
+
"spec/likeable/setup_spec.rb",
|
39
|
+
"spec/likeable/user_methods_spec.rb",
|
40
|
+
"spec/likeable_spec.rb",
|
41
|
+
"spec/spec_helper.rb"
|
42
|
+
]
|
43
|
+
s.homepage = "http://github.com/Schnems/likeable"
|
44
|
+
s.licenses = ["MIT"]
|
45
|
+
s.require_paths = ["lib"]
|
46
|
+
s.rubygems_version = "1.8.10"
|
47
|
+
s.summary = "Like ruby objects backed by redis"
|
48
|
+
s.test_files = [
|
49
|
+
"spec/likeable/facepile_spec.rb",
|
50
|
+
"spec/likeable/like_spec.rb",
|
51
|
+
"spec/likeable/module_methods_spec.rb",
|
52
|
+
"spec/likeable/setup_spec.rb",
|
53
|
+
"spec/likeable/user_methods_spec.rb",
|
54
|
+
"spec/likeable_spec.rb",
|
55
|
+
"spec/spec_helper.rb"
|
56
|
+
]
|
57
|
+
|
58
|
+
if s.respond_to? :specification_version then
|
59
|
+
s.specification_version = 3
|
60
|
+
|
61
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
62
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
63
|
+
s.add_runtime_dependency(%q<keytar>, [">= 1.5.2"])
|
64
|
+
s.add_runtime_dependency(%q<redis>, [">= 0"])
|
65
|
+
s.add_development_dependency(%q<activerecord>, ["~> 3.0.4"])
|
66
|
+
s.add_development_dependency(%q<rake>, ["~> 0.8.7"])
|
67
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
68
|
+
s.add_development_dependency(%q<autotest-standalone>, [">= 0"])
|
69
|
+
s.add_development_dependency(%q<autotest-growl>, [">= 0"])
|
70
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
71
|
+
else
|
72
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
73
|
+
s.add_dependency(%q<keytar>, [">= 1.5.2"])
|
74
|
+
s.add_dependency(%q<redis>, [">= 0"])
|
75
|
+
s.add_dependency(%q<activerecord>, ["~> 3.0.4"])
|
76
|
+
s.add_dependency(%q<rake>, ["~> 0.8.7"])
|
77
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
78
|
+
s.add_dependency(%q<autotest-standalone>, [">= 0"])
|
79
|
+
s.add_dependency(%q<autotest-growl>, [">= 0"])
|
80
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
81
|
+
end
|
82
|
+
else
|
83
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
84
|
+
s.add_dependency(%q<keytar>, [">= 1.5.2"])
|
85
|
+
s.add_dependency(%q<redis>, [">= 0"])
|
86
|
+
s.add_dependency(%q<activerecord>, ["~> 3.0.4"])
|
87
|
+
s.add_dependency(%q<rake>, ["~> 0.8.7"])
|
88
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
89
|
+
s.add_dependency(%q<autotest-standalone>, [">= 0"])
|
90
|
+
s.add_dependency(%q<autotest-growl>, [">= 0"])
|
91
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class CleanTestClassForLikeable
|
4
|
+
include Likeable
|
5
|
+
def like_key
|
6
|
+
"like_key"
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_hash(*args); {} end
|
10
|
+
|
11
|
+
def foo
|
12
|
+
end
|
13
|
+
|
14
|
+
def id
|
15
|
+
@id ||= rand(100)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
describe Likeable::Facepile do
|
21
|
+
before(:each) do
|
22
|
+
@user = User.new
|
23
|
+
@target = CleanTestClassForLikeable.new
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'facepile' do
|
27
|
+
before do
|
28
|
+
@friend_ids = [1,2,3,4]
|
29
|
+
@like_ids = [3,4,5,6,7,8,9,10,11,12]
|
30
|
+
@intersection = @friend_ids & @like_ids
|
31
|
+
end
|
32
|
+
describe '#ids_for_facepile' do
|
33
|
+
it 'builds a array of ids with friend ids and randoms if they have liked the object up to the limit' do
|
34
|
+
@target.should_receive(:liked_friend_ids).with(@user).and_return(@friend_ids)
|
35
|
+
@target.should_receive(:like_user_ids).and_return(@like_ids)
|
36
|
+
@target.ids_for_facepile(@user).should include(@intersection.sample)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'can be limited' do
|
40
|
+
limit = 3
|
41
|
+
@target.should_receive(:liked_friend_ids).and_return(@friend_ids)
|
42
|
+
@target.should_receive(:like_user_ids).and_return(@like_ids)
|
43
|
+
@target.ids_for_facepile(@user, limit).count.should eq(limit)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#users_for_facepile' do
|
48
|
+
it 'builds a array of users if they have liked the object' do
|
49
|
+
@target.should_receive(:ids_for_facepile).and_return(@friend_ids)
|
50
|
+
User.should_receive(:where).with(:id => @friend_ids)
|
51
|
+
@target.users_for_facepile(@user)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe Likeable::Like do
|
3
|
+
before do
|
4
|
+
@time = Time.now
|
5
|
+
end
|
6
|
+
describe 'attributes' do
|
7
|
+
it 'stores target, user, and created_at' do
|
8
|
+
like = Likeable::Like.new(:target => @target, :user => @user, :time => @time)
|
9
|
+
like.user.should eq(@user)
|
10
|
+
like.target.should eq(@target)
|
11
|
+
like.created_at.should eq(@time)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'converts float time to propper Time object' do
|
15
|
+
like = Likeable::Like.new(:time => @time.to_f)
|
16
|
+
like.created_at.should eq(@time)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class CleanTestClassForLikeable
|
4
|
+
include Likeable
|
5
|
+
def like_key
|
6
|
+
"like_key"
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_hash(*args); {} end
|
10
|
+
|
11
|
+
def foo
|
12
|
+
end
|
13
|
+
|
14
|
+
def id
|
15
|
+
@id ||= rand(100)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class LikeableIncludedInSetup
|
20
|
+
def like_key
|
21
|
+
"like_key"
|
22
|
+
end
|
23
|
+
|
24
|
+
def id
|
25
|
+
@id ||= rand(100)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe Likeable::Facepile do
|
30
|
+
before(:each) do
|
31
|
+
@user = User.new
|
32
|
+
@target = CleanTestClassForLikeable.new
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "module methods" do
|
36
|
+
describe ".model" do
|
37
|
+
it "takes a valid class string and turns it into a class" do
|
38
|
+
klass = CleanTestClassForLikeable
|
39
|
+
klass_name = klass.to_s
|
40
|
+
Likeable.model(klass_name).should eq(klass)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe ".find_by_resource_id" do
|
45
|
+
it "finds an active-record based object on a valid model and id" do
|
46
|
+
klass = CleanTestClassForLikeable
|
47
|
+
klass_name = klass.to_s
|
48
|
+
id = rand(1000)
|
49
|
+
klass.should_receive(:where).with(:id => id).and_return([])
|
50
|
+
Likeable.find_by_resource_id(klass_name, id)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "will return nil for an invalid object" do
|
54
|
+
klass = CleanTestClassForLikeable
|
55
|
+
klass_name = klass.to_s + "this makes this klass_name invalid"
|
56
|
+
|
57
|
+
Likeable.find_by_resource_id(klass_name, rand(1000)).should be_blank
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
class LikeableIncludedInSetup
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
class SetupCleanTestClassForLikeable
|
9
|
+
include Likeable
|
10
|
+
def like_key
|
11
|
+
"like_key"
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_hash(*args); {} end
|
15
|
+
|
16
|
+
def foo
|
17
|
+
end
|
18
|
+
|
19
|
+
def id
|
20
|
+
@id ||= rand(100)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe Likeable do
|
25
|
+
before(:each) do
|
26
|
+
reload_user!
|
27
|
+
Likeable.user_class = User
|
28
|
+
@user = User.new
|
29
|
+
@target = SetupCleanTestClassForLikeable.new
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
describe "Likeable setup" do
|
34
|
+
it "adds Likeable::UserMethods to User" do
|
35
|
+
describe User.ancestors do
|
36
|
+
it {should_not include Likeable::UserMethods}
|
37
|
+
end
|
38
|
+
Likeable.setup
|
39
|
+
describe User.ancestors do
|
40
|
+
it {should include Likeable::UserMethods}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "adds likeable to class" do
|
45
|
+
Likeable.setup do |like|
|
46
|
+
like.classes = LikeableIncludedInSetup
|
47
|
+
end
|
48
|
+
|
49
|
+
describe LikeableIncludedInSetup.ancestors do
|
50
|
+
it {should include Likeable}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "" do
|
55
|
+
result = "foo"
|
56
|
+
Likeable.setup
|
57
|
+
|
58
|
+
Likeable.after_like do |like|
|
59
|
+
result = "after_like_called_successfully"
|
60
|
+
end
|
61
|
+
|
62
|
+
@user.like! @target
|
63
|
+
result.should == "after_like_called_successfully"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class CleanTestClassForLikeable
|
4
|
+
include Likeable
|
5
|
+
def like_key
|
6
|
+
"like_key"
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_hash(*args); {} end
|
10
|
+
|
11
|
+
def foo
|
12
|
+
end
|
13
|
+
|
14
|
+
def id
|
15
|
+
@id ||= rand(100)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Likeable.setup
|
20
|
+
|
21
|
+
describe Likeable::UserMethods do
|
22
|
+
before(:each) do
|
23
|
+
@user = User.new
|
24
|
+
@target = CleanTestClassForLikeable.new
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#like!' do
|
28
|
+
it "calls add_like_from in target" do
|
29
|
+
@target.should_receive(:add_like_from).with(@user)
|
30
|
+
@user.like! @target
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#unlike!' do
|
35
|
+
it "calls remove_like_from in target" do
|
36
|
+
@target.should_receive(:remove_like_from).with(@user)
|
37
|
+
@user.unlike! @target
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#like?' do
|
42
|
+
it "calls liked_by? in target" do
|
43
|
+
@target.should_receive(:liked_by?).with(@user)
|
44
|
+
@user.like? @target
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#like?' do
|
49
|
+
it "calls liked_by? in target" do
|
50
|
+
@target.should_receive(:liked_by?).with(@user)
|
51
|
+
@user.like? @target
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#friend_ids_that_like' do
|
56
|
+
it "calls liked_friend_ids? in target" do
|
57
|
+
@target.should_receive(:liked_friend_ids).with(@user)
|
58
|
+
@user.friend_ids_that_like @target
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#friends_that_like' do
|
63
|
+
it "calls liked_friends? in target" do
|
64
|
+
@target.should_receive(:liked_friends).with(@user, nil)
|
65
|
+
@user.friends_that_like @target
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
class CleanTestClassForLikeable
|
3
|
+
include Likeable
|
4
|
+
def like_key
|
5
|
+
"like_key"
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_hash(*args); {} end
|
9
|
+
|
10
|
+
def foo
|
11
|
+
end
|
12
|
+
|
13
|
+
def id
|
14
|
+
@id ||= rand(100)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
Likeable.setup do |like|
|
22
|
+
like.find_one = lambda {|klass, id| klass.where(:id => id)}
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
describe Likeable do
|
27
|
+
|
28
|
+
before(:each) do
|
29
|
+
@user = User.new
|
30
|
+
@target = CleanTestClassForLikeable.new
|
31
|
+
end
|
32
|
+
describe 'instance methods' do
|
33
|
+
|
34
|
+
describe "#add_like_from" do
|
35
|
+
it "creates a like" do
|
36
|
+
target_class = @target.class.to_s.downcase
|
37
|
+
user_like_key = "users:like:#{@user.id}:#{target_class}"
|
38
|
+
time = Time.now.to_f
|
39
|
+
@user.should_receive(:like_key).with(target_class).and_return(user_like_key)
|
40
|
+
Likeable.redis.should_receive(:hset).with("like_key", @user.id, time).once
|
41
|
+
Likeable.redis.should_receive(:hset).with(user_like_key, @target.id, time).once
|
42
|
+
@target.add_like_from(@user, time)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#remove_like_from" do
|
47
|
+
it "removes a like" do
|
48
|
+
target_class = @target.class.to_s.downcase
|
49
|
+
user_like_key = "users:like:#{@user.id}:#{target_class}"
|
50
|
+
@user.should_receive(:like_key).with(target_class).and_return(user_like_key)
|
51
|
+
Likeable.redis.should_receive(:hdel).with("like_key", @user.id).once
|
52
|
+
Likeable.redis.should_receive(:hdel).with(user_like_key, @target.id)
|
53
|
+
@target.remove_like_from(@user)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#likes" do
|
58
|
+
it "returns set of likes" do
|
59
|
+
Likeable.redis.should_receive(:hkeys).with("like_key").once
|
60
|
+
@target.like_user_ids
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#liked_by?" do
|
65
|
+
it "will answer if current user likes target" do
|
66
|
+
Likeable.redis.should_receive(:hexists).with("like_key", @user.id).once
|
67
|
+
@target.liked_by?(@user)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#liked_friend_ids" do
|
72
|
+
it "will return all friend ids of user who like target" do
|
73
|
+
common_value = 3
|
74
|
+
@target.should_receive(:like_user_ids).and_return([1,2, common_value])
|
75
|
+
@user.should_receive(:friend_ids).and_return([common_value])
|
76
|
+
@target.liked_friend_ids(@user).should == [common_value]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#liked_friends" do
|
81
|
+
it "will return all friends who like object" do
|
82
|
+
values = [1]
|
83
|
+
@target.should_receive(:liked_friend_ids).with(@user).and_return(values)
|
84
|
+
User.should_receive(:where).with(:id => values)
|
85
|
+
@target.liked_friends(@user)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "class methods" do
|
91
|
+
describe 'after_like' do
|
92
|
+
it 'should be a class method when included' do
|
93
|
+
CleanTestClassForLikeable.respond_to?(:after_like).should be_true
|
94
|
+
end
|
95
|
+
it 'is called after a like is created' do
|
96
|
+
CleanTestClassForLikeable.after_like(:foo)
|
97
|
+
@target.should_receive(:foo)
|
98
|
+
@target.add_like_from(@user)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../..', 'lib'))
|
7
|
+
|
8
|
+
|
9
|
+
def build_user!
|
10
|
+
eval %Q{
|
11
|
+
class User
|
12
|
+
def id
|
13
|
+
@time ||= Time.now.to_f.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.where(*args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def friends_ids
|
20
|
+
[]
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.after_destroy
|
24
|
+
end
|
25
|
+
end
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def unload_user!
|
30
|
+
Object.instance_eval{ remove_const :User }
|
31
|
+
end
|
32
|
+
|
33
|
+
def reload_user!
|
34
|
+
unload_user!
|
35
|
+
build_user!
|
36
|
+
end
|
37
|
+
|
38
|
+
build_user!
|
39
|
+
|
40
|
+
require 'likeable'
|
41
|
+
|
42
|
+
require 'rspec'
|
43
|
+
require 'rspec/autorun'
|
44
|
+
|
metadata
ADDED
@@ -0,0 +1,226 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: likeable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Schneems
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-10-12 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
22
|
+
none: false
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
hash: 3
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
name: activesupport
|
31
|
+
prerelease: false
|
32
|
+
type: :runtime
|
33
|
+
requirement: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
hash: 7
|
41
|
+
segments:
|
42
|
+
- 1
|
43
|
+
- 5
|
44
|
+
- 2
|
45
|
+
version: 1.5.2
|
46
|
+
name: keytar
|
47
|
+
prerelease: false
|
48
|
+
type: :runtime
|
49
|
+
requirement: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
name: redis
|
61
|
+
prerelease: false
|
62
|
+
type: :runtime
|
63
|
+
requirement: *id003
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 15
|
71
|
+
segments:
|
72
|
+
- 3
|
73
|
+
- 0
|
74
|
+
- 4
|
75
|
+
version: 3.0.4
|
76
|
+
name: activerecord
|
77
|
+
prerelease: false
|
78
|
+
type: :development
|
79
|
+
requirement: *id004
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ~>
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 49
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
- 8
|
90
|
+
- 7
|
91
|
+
version: 0.8.7
|
92
|
+
name: rake
|
93
|
+
prerelease: false
|
94
|
+
type: :development
|
95
|
+
requirement: *id005
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ~>
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
hash: 7
|
103
|
+
segments:
|
104
|
+
- 1
|
105
|
+
- 5
|
106
|
+
- 2
|
107
|
+
version: 1.5.2
|
108
|
+
name: jeweler
|
109
|
+
prerelease: false
|
110
|
+
type: :development
|
111
|
+
requirement: *id006
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
hash: 3
|
119
|
+
segments:
|
120
|
+
- 0
|
121
|
+
version: "0"
|
122
|
+
name: autotest-standalone
|
123
|
+
prerelease: false
|
124
|
+
type: :development
|
125
|
+
requirement: *id007
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
hash: 3
|
133
|
+
segments:
|
134
|
+
- 0
|
135
|
+
version: "0"
|
136
|
+
name: autotest-growl
|
137
|
+
prerelease: false
|
138
|
+
type: :development
|
139
|
+
requirement: *id008
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
version_requirements: &id009 !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
hash: 3
|
147
|
+
segments:
|
148
|
+
- 0
|
149
|
+
version: "0"
|
150
|
+
name: rspec
|
151
|
+
prerelease: false
|
152
|
+
type: :development
|
153
|
+
requirement: *id009
|
154
|
+
description: "\n Likeable allows you to make your models...well...likeable using redis.\n "
|
155
|
+
email: richard.schneeman@gmail.com
|
156
|
+
executables: []
|
157
|
+
|
158
|
+
extensions: []
|
159
|
+
|
160
|
+
extra_rdoc_files:
|
161
|
+
- README.md
|
162
|
+
files:
|
163
|
+
- .autotest
|
164
|
+
- .rspec
|
165
|
+
- .rvmrc
|
166
|
+
- Gemfile
|
167
|
+
- README.md
|
168
|
+
- Rakefile
|
169
|
+
- VERSION
|
170
|
+
- autotest/discover.rb
|
171
|
+
- lib/.DS_Store
|
172
|
+
- lib/likeable.rb
|
173
|
+
- lib/likeable/facepile.rb
|
174
|
+
- lib/likeable/like.rb
|
175
|
+
- lib/likeable/module_methods.rb
|
176
|
+
- lib/likeable/user_methods.rb
|
177
|
+
- license.txt
|
178
|
+
- likeable.gemspec
|
179
|
+
- spec/likeable/facepile_spec.rb
|
180
|
+
- spec/likeable/like_spec.rb
|
181
|
+
- spec/likeable/module_methods_spec.rb
|
182
|
+
- spec/likeable/setup_spec.rb
|
183
|
+
- spec/likeable/user_methods_spec.rb
|
184
|
+
- spec/likeable_spec.rb
|
185
|
+
- spec/spec_helper.rb
|
186
|
+
homepage: http://github.com/Schnems/likeable
|
187
|
+
licenses:
|
188
|
+
- MIT
|
189
|
+
post_install_message:
|
190
|
+
rdoc_options: []
|
191
|
+
|
192
|
+
require_paths:
|
193
|
+
- lib
|
194
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
195
|
+
none: false
|
196
|
+
requirements:
|
197
|
+
- - ">="
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
hash: 3
|
200
|
+
segments:
|
201
|
+
- 0
|
202
|
+
version: "0"
|
203
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
204
|
+
none: false
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
hash: 3
|
209
|
+
segments:
|
210
|
+
- 0
|
211
|
+
version: "0"
|
212
|
+
requirements: []
|
213
|
+
|
214
|
+
rubyforge_project:
|
215
|
+
rubygems_version: 1.8.10
|
216
|
+
signing_key:
|
217
|
+
specification_version: 3
|
218
|
+
summary: Like ruby objects backed by redis
|
219
|
+
test_files:
|
220
|
+
- spec/likeable/facepile_spec.rb
|
221
|
+
- spec/likeable/like_spec.rb
|
222
|
+
- spec/likeable/module_methods_spec.rb
|
223
|
+
- spec/likeable/setup_spec.rb
|
224
|
+
- spec/likeable/user_methods_spec.rb
|
225
|
+
- spec/likeable_spec.rb
|
226
|
+
- spec/spec_helper.rb
|