socialization 0.4.0 → 0.5.0.beta
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/.gitignore +5 -1
- data/CHANGELOG.md +41 -0
- data/README.md +246 -0
- data/demo/{demo_app/.gitignore → .gitignore} +0 -0
- data/demo/{demo_app/Gemfile → Gemfile} +1 -1
- data/demo/{demo_app/README.rdoc → README.rdoc} +0 -0
- data/demo/{demo_app/Rakefile → Rakefile} +0 -0
- data/demo/{demo_app/app → app}/assets/images/rails.png +0 -0
- data/demo/{demo_app/app → app}/assets/javascripts/application.js +0 -0
- data/demo/{demo_app/app → app}/assets/stylesheets/application.css +0 -0
- data/demo/{demo_app/app → app}/controllers/application_controller.rb +0 -0
- data/demo/{demo_app/app → app}/helpers/application_helper.rb +0 -0
- data/demo/{demo_app/app → app}/mailers/.gitkeep +0 -0
- data/demo/{demo_app/app → app}/models/.gitkeep +0 -0
- data/demo/{demo_app/app → app}/models/celebrity.rb +0 -0
- data/demo/{demo_app/app → app}/models/comment.rb +0 -0
- data/demo/app/models/follow.rb +2 -0
- data/demo/app/models/like.rb +2 -0
- data/demo/app/models/mention.rb +2 -0
- data/demo/{demo_app/app → app}/models/movie.rb +0 -0
- data/demo/{demo_app/app → app}/models/user.rb +0 -0
- data/demo/{demo_app/app → app}/views/layouts/application.html.erb +0 -0
- data/demo/{demo_app/config.ru → config.ru} +0 -0
- data/demo/{demo_app/config → config}/application.rb +0 -0
- data/demo/{demo_app/config → config}/boot.rb +0 -0
- data/demo/{demo_app/config → config}/database.yml +0 -0
- data/demo/{demo_app/config → config}/environment.rb +0 -0
- data/demo/{demo_app/config → config}/environments/development.rb +0 -0
- data/demo/{demo_app/config → config}/environments/production.rb +0 -0
- data/demo/{demo_app/config → config}/environments/test.rb +0 -0
- data/demo/{demo_app/config → config}/initializers/backtrace_silencers.rb +0 -0
- data/demo/{demo_app/config → config}/initializers/inflections.rb +0 -0
- data/demo/{demo_app/config → config}/initializers/mime_types.rb +0 -0
- data/demo/{demo_app/config → config}/initializers/secret_token.rb +0 -0
- data/demo/{demo_app/config → config}/initializers/session_store.rb +1 -1
- data/demo/{demo_app/config → config}/initializers/wrap_parameters.rb +1 -1
- data/demo/{demo_app/config → config}/locales/en.yml +0 -0
- data/demo/{demo_app/config → config}/routes.rb +0 -0
- data/demo/{demo_app/db → db}/migrate/20120115051222_create_users.rb +0 -0
- data/demo/{demo_app/db → db}/migrate/20120115051234_create_movies.rb +0 -0
- data/demo/{demo_app/db → db}/migrate/20120115051255_create_celebrities.rb +0 -0
- data/demo/{demo_app/db → db}/migrate/20120115054646_create_follows.rb +0 -0
- data/demo/{demo_app/db → db}/migrate/20120115054647_create_likes.rb +0 -0
- data/demo/{demo_app/db → db}/migrate/20120221200644_create_mentions.rb +0 -0
- data/demo/{demo_app/db → db}/migrate/20120221202703_create_comments.rb +0 -0
- data/demo/{demo_app/db → db}/schema.rb +0 -1
- data/demo/{demo_app/db → db}/seeds.rb +0 -0
- data/demo/{demo_app/lib → lib}/assets/.gitkeep +0 -0
- data/demo/{demo_app/lib → lib}/tasks/.gitkeep +0 -0
- data/demo/{demo_app/public → public}/404.html +0 -0
- data/demo/{demo_app/public → public}/422.html +0 -0
- data/demo/{demo_app/public → public}/500.html +0 -0
- data/demo/{demo_app/public → public}/favicon.ico +0 -0
- data/demo/{demo_app/public → public}/index.html +0 -0
- data/demo/{demo_app/public → public}/robots.txt +0 -0
- data/demo/{demo_app/script → script}/rails +0 -0
- data/demo/{demo_app/test → test}/fixtures/.gitkeep +0 -0
- data/demo/{demo_app/test → test}/fixtures/celebrities.yml +0 -0
- data/demo/{demo_app/test → test}/fixtures/movies.yml +0 -0
- data/demo/{demo_app/test → test}/fixtures/users.yml +0 -0
- data/demo/{demo_app/test → test}/functional/.gitkeep +0 -0
- data/demo/{demo_app/test → test}/integration/.gitkeep +0 -0
- data/demo/{demo_app/test → test}/performance/browsing_test.rb +0 -0
- data/demo/{demo_app/test → test}/test_helper.rb +0 -0
- data/demo/{demo_app/test → test}/unit/.gitkeep +0 -0
- data/demo/{demo_app/test → test}/unit/celebrity_test.rb +0 -0
- data/demo/{demo_app/test → test}/unit/movie_test.rb +0 -0
- data/demo/{demo_app/test → test}/unit/user_test.rb +0 -0
- data/demo/{demo_app/vendor → vendor}/assets/javascripts/.gitkeep +0 -0
- data/demo/{demo_app/vendor → vendor}/assets/stylesheets/.gitkeep +0 -0
- data/demo/{demo_app/vendor → vendor}/plugins/.gitkeep +0 -0
- data/lib/generators/socialization/socialization_generator.rb +20 -9
- data/{generators/socialization/templates → lib/generators/socialization/templates/active_record}/migration_follows.rb +0 -0
- data/{generators/socialization/templates → lib/generators/socialization/templates/active_record}/migration_likes.rb +0 -0
- data/{generators/socialization/templates → lib/generators/socialization/templates/active_record}/migration_mentions.rb +0 -0
- data/lib/generators/socialization/templates/active_record/model_follow.rb +2 -0
- data/lib/generators/socialization/templates/active_record/model_like.rb +2 -0
- data/lib/generators/socialization/templates/active_record/model_mention.rb +2 -0
- data/lib/socialization.rb +3 -5
- data/lib/socialization/actors/follower.rb +74 -0
- data/lib/socialization/actors/liker.rb +74 -0
- data/lib/socialization/actors/mentioner.rb +74 -0
- data/lib/socialization/acts_as_helpers.rb +43 -0
- data/lib/socialization/config.rb +45 -0
- data/lib/socialization/helpers/string.rb +17 -0
- data/lib/socialization/stores/active_record/follow_store.rb +143 -0
- data/lib/socialization/stores/active_record/like_store.rb +143 -0
- data/lib/socialization/stores/active_record/mention_store.rb +143 -0
- data/lib/socialization/stores/redis/base.rb +8 -0
- data/lib/socialization/stores/redis/config.rb +11 -0
- data/lib/socialization/stores/redis/follow_store.rb +126 -0
- data/lib/socialization/stores/redis/like_store.rb +126 -0
- data/lib/socialization/stores/redis/mention_store.rb +126 -0
- data/lib/socialization/version.rb +1 -1
- data/lib/socialization/victims/followable.rb +38 -0
- data/lib/socialization/victims/likeable.rb +38 -0
- data/lib/socialization/victims/mentionable.rb +38 -0
- data/socialization.gemspec +3 -3
- data/test/actors/follower_test.rb +74 -0
- data/test/actors/liker_test.rb +74 -0
- data/test/actors/mentioner_test.rb +74 -0
- data/test/stores/active_record/follow_store_test.rb +121 -0
- data/test/stores/active_record/like_store_test.rb +121 -0
- data/test/stores/active_record/mention_store_test.rb +121 -0
- data/test/stores/redis/config_test.rb +30 -0
- data/test/stores/redis/follow_store_test.rb +153 -0
- data/test/stores/redis/like_store_test.rb +153 -0
- data/test/stores/redis/mention_store_test.rb +153 -0
- data/test/string_test.rb +13 -0
- data/test/test_helper.rb +70 -12
- data/test/victims/followable_test.rb +34 -0
- data/test/victims/likeable_test.rb +34 -0
- data/test/victims/mentionable_test.rb +34 -0
- data/test/world_test.rb +80 -69
- metadata +261 -176
- data/README.rdoc +0 -186
- data/demo/demo_app/app/models/follow.rb +0 -3
- data/demo/demo_app/app/models/like.rb +0 -3
- data/demo/demo_app/app/models/mention.rb +0 -3
- data/demo/demo_app/doc/README_FOR_APP +0 -2
- data/gemfiles/activerecord30.gemfile +0 -6
- data/gemfiles/activerecord30.gemfile.lock +0 -23
- data/gemfiles/activerecord31.gemfile +0 -6
- data/gemfiles/activerecord31.gemfile.lock +0 -25
- data/gemfiles/activerecord32.gemfile +0 -6
- data/gemfiles/activerecord32.gemfile.lock +0 -25
- data/generators/socialization/USAGE +0 -1
- data/generators/socialization/socialization_generator.rb +0 -15
- data/generators/socialization/templates/model_follow.rb +0 -3
- data/generators/socialization/templates/model_like.rb +0 -3
- data/generators/socialization/templates/model_mention.rb +0 -3
- data/lib/socialization/follow_store.rb +0 -14
- data/lib/socialization/followable.rb +0 -34
- data/lib/socialization/follower.rb +0 -50
- data/lib/socialization/hello.rb +0 -53
- data/lib/socialization/like_store.rb +0 -14
- data/lib/socialization/likeable.rb +0 -34
- data/lib/socialization/liker.rb +0 -54
- data/lib/socialization/mention_store.rb +0 -14
- data/lib/socialization/mentionable.rb +0 -36
- data/lib/socialization/mentioner.rb +0 -54
- data/test/follow_test.rb +0 -125
- data/test/like_test.rb +0 -125
- data/test/mention_test.rb +0 -116
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)) + '/base'
|
|
2
|
+
|
|
3
|
+
module Socialization
|
|
4
|
+
module RedisStores
|
|
5
|
+
class FollowStore < Socialization::RedisStores::Base
|
|
6
|
+
class << self
|
|
7
|
+
def follow!(follower, followable)
|
|
8
|
+
unless follows?(follower, followable)
|
|
9
|
+
Socialization.redis.sadd generate_followers_key(follower, followable), follower.id
|
|
10
|
+
Socialization.redis.sadd generate_followables_key(follower, followable), followable.id
|
|
11
|
+
|
|
12
|
+
call_after_create_hook(follower, followable)
|
|
13
|
+
follower.touch if [:all, :follower].include?(touch) && follower.respond_to?(:touch)
|
|
14
|
+
followable.touch if [:all, :followable].include?(touch) && followable.respond_to?(:touch)
|
|
15
|
+
true
|
|
16
|
+
else
|
|
17
|
+
false
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def unfollow!(follower, followable)
|
|
22
|
+
if follows?(follower, followable)
|
|
23
|
+
Socialization.redis.srem generate_followers_key(follower, followable), follower.id
|
|
24
|
+
Socialization.redis.srem generate_followables_key(follower, followable), followable.id
|
|
25
|
+
|
|
26
|
+
call_after_destroy_hook(follower, followable)
|
|
27
|
+
follower.touch if [:all, :follower].include?(touch) && follower.respond_to?(:touch)
|
|
28
|
+
followable.touch if [:all, :followable].include?(touch) && followable.respond_to?(:touch)
|
|
29
|
+
true
|
|
30
|
+
else
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def follows?(follower, followable)
|
|
36
|
+
Socialization.redis.sismember generate_followers_key(follower, followable), follower.id
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns an ActiveRecord::Relation of all the followers of a certain type that are following followable
|
|
40
|
+
def followers_relation(followable, klass, opts = {})
|
|
41
|
+
ids = followers(followable, klass, :pluck => :id)
|
|
42
|
+
klass.where('id IN (?)', ids)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Returns all the followers of a certain type that are following followable
|
|
46
|
+
def followers(followable, klass, opts = {})
|
|
47
|
+
if opts[:pluck]
|
|
48
|
+
Socialization.redis.smembers(generate_followers_key(klass, followable)).map { |id|
|
|
49
|
+
id.to_i if id.is_integer?
|
|
50
|
+
}
|
|
51
|
+
else
|
|
52
|
+
followers_relation(followable, klass, opts).all
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns an ActiveRecord::Relation of all the followables of a certain type that are followed by follower
|
|
57
|
+
def followables_relation(follower, klass, opts = {})
|
|
58
|
+
ids = followables(follower, klass, :pluck => :id)
|
|
59
|
+
klass.where('id IN (?)', ids)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns all the followables of a certain type that are followed by follower
|
|
63
|
+
def followables(follower, klass, opts = {})
|
|
64
|
+
if opts[:pluck]
|
|
65
|
+
Socialization.redis.smembers(generate_followables_key(follower, klass)).map { |id|
|
|
66
|
+
id.to_i if id.is_integer?
|
|
67
|
+
}
|
|
68
|
+
else
|
|
69
|
+
followables_relation(follower, klass, opts).all
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def touch(what = nil)
|
|
74
|
+
if what.nil?
|
|
75
|
+
@touch || false
|
|
76
|
+
else
|
|
77
|
+
raise ArgumentError unless [:all, :follower, :followable, false, nil].include?(what)
|
|
78
|
+
@touch = what
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def after_follow(method)
|
|
83
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
84
|
+
@after_create_hook = method
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def after_unfollow(method)
|
|
88
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
89
|
+
@after_destroy_hook = method
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
def call_after_create_hook(follower, followable)
|
|
94
|
+
self.send(@after_create_hook, follower, followable) if @after_create_hook
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def call_after_destroy_hook(follower, followable)
|
|
98
|
+
self.send(@after_destroy_hook, follower, followable) if @after_destroy_hook
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def generate_followers_key(follower, followable)
|
|
102
|
+
raise ArgumentError.new("`followable` needs to be an acts_as_followable objecs, not a class.") if followable.class == Class
|
|
103
|
+
follower_class = if follower.class == Class
|
|
104
|
+
follower
|
|
105
|
+
else
|
|
106
|
+
follower.class
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
"Followers:#{followable.class}:#{followable.id}:#{follower_class}"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def generate_followables_key(follower, followable)
|
|
113
|
+
raise ArgumentError.new("`follower` needs to be an acts_as_follower object, not a class.") if follower.class == Class
|
|
114
|
+
followable_class = if followable.class == Class
|
|
115
|
+
followable
|
|
116
|
+
else
|
|
117
|
+
followable.class
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
"Followables:#{follower.class}:#{follower.id}:#{followable_class}"
|
|
121
|
+
end
|
|
122
|
+
end # class << self
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)) + '/base'
|
|
2
|
+
|
|
3
|
+
module Socialization
|
|
4
|
+
module RedisStores
|
|
5
|
+
class LikeStore < Socialization::RedisStores::Base
|
|
6
|
+
class << self
|
|
7
|
+
def like!(liker, likeable)
|
|
8
|
+
unless likes?(liker, likeable)
|
|
9
|
+
Socialization.redis.sadd generate_likers_key(liker, likeable), liker.id
|
|
10
|
+
Socialization.redis.sadd generate_likeables_key(liker, likeable), likeable.id
|
|
11
|
+
|
|
12
|
+
call_after_create_hook(liker, likeable)
|
|
13
|
+
liker.touch if [:all, :liker].include?(touch) && liker.respond_to?(:touch)
|
|
14
|
+
likeable.touch if [:all, :likeable].include?(touch) && likeable.respond_to?(:touch)
|
|
15
|
+
true
|
|
16
|
+
else
|
|
17
|
+
false
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def unlike!(liker, likeable)
|
|
22
|
+
if likes?(liker, likeable)
|
|
23
|
+
Socialization.redis.srem generate_likers_key(liker, likeable), liker.id
|
|
24
|
+
Socialization.redis.srem generate_likeables_key(liker, likeable), likeable.id
|
|
25
|
+
|
|
26
|
+
call_after_destroy_hook(liker, likeable)
|
|
27
|
+
liker.touch if [:all, :liker].include?(touch) && liker.respond_to?(:touch)
|
|
28
|
+
likeable.touch if [:all, :likeable].include?(touch) && likeable.respond_to?(:touch)
|
|
29
|
+
true
|
|
30
|
+
else
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def likes?(liker, likeable)
|
|
36
|
+
Socialization.redis.sismember generate_likers_key(liker, likeable), liker.id
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns an ActiveRecord::Relation of all the likers of a certain type that are likeing likeable
|
|
40
|
+
def likers_relation(likeable, klass, opts = {})
|
|
41
|
+
ids = likers(likeable, klass, :pluck => :id)
|
|
42
|
+
klass.where('id IN (?)', ids)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Returns all the likers of a certain type that are likeing likeable
|
|
46
|
+
def likers(likeable, klass, opts = {})
|
|
47
|
+
if opts[:pluck]
|
|
48
|
+
Socialization.redis.smembers(generate_likers_key(klass, likeable)).map { |id|
|
|
49
|
+
id.to_i if id.is_integer?
|
|
50
|
+
}
|
|
51
|
+
else
|
|
52
|
+
likers_relation(likeable, klass, opts).all
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns an ActiveRecord::Relation of all the likeables of a certain type that are liked by liker
|
|
57
|
+
def likeables_relation(liker, klass, opts = {})
|
|
58
|
+
ids = likeables(liker, klass, :pluck => :id)
|
|
59
|
+
klass.where('id IN (?)', ids)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns all the likeables of a certain type that are liked by liker
|
|
63
|
+
def likeables(liker, klass, opts = {})
|
|
64
|
+
if opts[:pluck]
|
|
65
|
+
Socialization.redis.smembers(generate_likeables_key(liker, klass)).map { |id|
|
|
66
|
+
id.to_i if id.is_integer?
|
|
67
|
+
}
|
|
68
|
+
else
|
|
69
|
+
likeables_relation(liker, klass, opts).all
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def touch(what = nil)
|
|
74
|
+
if what.nil?
|
|
75
|
+
@touch || false
|
|
76
|
+
else
|
|
77
|
+
raise ArgumentError unless [:all, :liker, :likeable, false, nil].include?(what)
|
|
78
|
+
@touch = what
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def after_like(method)
|
|
83
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
84
|
+
@after_create_hook = method
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def after_unlike(method)
|
|
88
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
89
|
+
@after_destroy_hook = method
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
def call_after_create_hook(liker, likeable)
|
|
94
|
+
self.send(@after_create_hook, liker, likeable) if @after_create_hook
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def call_after_destroy_hook(liker, likeable)
|
|
98
|
+
self.send(@after_destroy_hook, liker, likeable) if @after_destroy_hook
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def generate_likers_key(liker, likeable)
|
|
102
|
+
raise ArgumentError.new("`likeable` needs to be an acts_as_likeable objecs, not a class.") if likeable.class == Class
|
|
103
|
+
liker_class = if liker.class == Class
|
|
104
|
+
liker
|
|
105
|
+
else
|
|
106
|
+
liker.class
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
"Likers:#{likeable.class}:#{likeable.id}:#{liker_class}"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def generate_likeables_key(liker, likeable)
|
|
113
|
+
raise ArgumentError.new("`liker` needs to be an acts_as_liker object, not a class.") if liker.class == Class
|
|
114
|
+
likeable_class = if likeable.class == Class
|
|
115
|
+
likeable
|
|
116
|
+
else
|
|
117
|
+
likeable.class
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
"Likeables:#{liker.class}:#{liker.id}:#{likeable_class}"
|
|
121
|
+
end
|
|
122
|
+
end # class << self
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)) + '/base'
|
|
2
|
+
|
|
3
|
+
module Socialization
|
|
4
|
+
module RedisStores
|
|
5
|
+
class MentionStore < Socialization::RedisStores::Base
|
|
6
|
+
class << self
|
|
7
|
+
def mention!(mentioner, mentionable)
|
|
8
|
+
unless mentions?(mentioner, mentionable)
|
|
9
|
+
Socialization.redis.sadd generate_mentioners_key(mentioner, mentionable), mentioner.id
|
|
10
|
+
Socialization.redis.sadd generate_mentionables_key(mentioner, mentionable), mentionable.id
|
|
11
|
+
|
|
12
|
+
call_after_create_hook(mentioner, mentionable)
|
|
13
|
+
mentioner.touch if [:all, :mentioner].include?(touch) && mentioner.respond_to?(:touch)
|
|
14
|
+
mentionable.touch if [:all, :mentionable].include?(touch) && mentionable.respond_to?(:touch)
|
|
15
|
+
true
|
|
16
|
+
else
|
|
17
|
+
false
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def unmention!(mentioner, mentionable)
|
|
22
|
+
if mentions?(mentioner, mentionable)
|
|
23
|
+
Socialization.redis.srem generate_mentioners_key(mentioner, mentionable), mentioner.id
|
|
24
|
+
Socialization.redis.srem generate_mentionables_key(mentioner, mentionable), mentionable.id
|
|
25
|
+
|
|
26
|
+
call_after_destroy_hook(mentioner, mentionable)
|
|
27
|
+
mentioner.touch if [:all, :mentioner].include?(touch) && mentioner.respond_to?(:touch)
|
|
28
|
+
mentionable.touch if [:all, :mentionable].include?(touch) && mentionable.respond_to?(:touch)
|
|
29
|
+
true
|
|
30
|
+
else
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def mentions?(mentioner, mentionable)
|
|
36
|
+
Socialization.redis.sismember generate_mentioners_key(mentioner, mentionable), mentioner.id
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns an ActiveRecord::Relation of all the mentioners of a certain type that are mentioning mentionable
|
|
40
|
+
def mentioners_relation(mentionable, klass, opts = {})
|
|
41
|
+
ids = mentioners(mentionable, klass, :pluck => :id)
|
|
42
|
+
klass.where('id IN (?)', ids)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Returns all the mentioners of a certain type that are mentioning mentionable
|
|
46
|
+
def mentioners(mentionable, klass, opts = {})
|
|
47
|
+
if opts[:pluck]
|
|
48
|
+
Socialization.redis.smembers(generate_mentioners_key(klass, mentionable)).map { |id|
|
|
49
|
+
id.to_i if id.is_integer?
|
|
50
|
+
}
|
|
51
|
+
else
|
|
52
|
+
mentioners_relation(mentionable, klass, opts).all
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns an ActiveRecord::Relation of all the mentionables of a certain type that are mentioned by mentioner
|
|
57
|
+
def mentionables_relation(mentioner, klass, opts = {})
|
|
58
|
+
ids = mentionables(mentioner, klass, :pluck => :id)
|
|
59
|
+
klass.where('id IN (?)', ids)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns all the mentionables of a certain type that are mentioned by mentioner
|
|
63
|
+
def mentionables(mentioner, klass, opts = {})
|
|
64
|
+
if opts[:pluck]
|
|
65
|
+
Socialization.redis.smembers(generate_mentionables_key(mentioner, klass)).map { |id|
|
|
66
|
+
id.to_i if id.is_integer?
|
|
67
|
+
}
|
|
68
|
+
else
|
|
69
|
+
mentionables_relation(mentioner, klass, opts).all
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def touch(what = nil)
|
|
74
|
+
if what.nil?
|
|
75
|
+
@touch || false
|
|
76
|
+
else
|
|
77
|
+
raise ArgumentError unless [:all, :mentioner, :mentionable, false, nil].include?(what)
|
|
78
|
+
@touch = what
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def after_mention(method)
|
|
83
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
84
|
+
@after_create_hook = method
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def after_unmention(method)
|
|
88
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
89
|
+
@after_destroy_hook = method
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
def call_after_create_hook(mentioner, mentionable)
|
|
94
|
+
self.send(@after_create_hook, mentioner, mentionable) if @after_create_hook
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def call_after_destroy_hook(mentioner, mentionable)
|
|
98
|
+
self.send(@after_destroy_hook, mentioner, mentionable) if @after_destroy_hook
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def generate_mentioners_key(mentioner, mentionable)
|
|
102
|
+
raise ArgumentError.new("`mentionable` needs to be an acts_as_mentionable objecs, not a class.") if mentionable.class == Class
|
|
103
|
+
mentioner_class = if mentioner.class == Class
|
|
104
|
+
mentioner
|
|
105
|
+
else
|
|
106
|
+
mentioner.class
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
"Mentioners:#{mentionable.class}:#{mentionable.id}:#{mentioner_class}"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def generate_mentionables_key(mentioner, mentionable)
|
|
113
|
+
raise ArgumentError.new("`mentioner` needs to be an acts_as_mentioner object, not a class.") if mentioner.class == Class
|
|
114
|
+
mentionable_class = if mentionable.class == Class
|
|
115
|
+
mentionable
|
|
116
|
+
else
|
|
117
|
+
mentionable.class
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
"Mentionables:#{mentioner.class}:#{mentioner.id}:#{mentionable_class}"
|
|
121
|
+
end
|
|
122
|
+
end # class << self
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
class Base
|
|
3
|
+
def is_followable?
|
|
4
|
+
false
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module Socialization
|
|
10
|
+
module Followable
|
|
11
|
+
extend ActiveSupport::Concern
|
|
12
|
+
|
|
13
|
+
included do
|
|
14
|
+
# Specifies if self can be followed.
|
|
15
|
+
#
|
|
16
|
+
# @return [Boolean]
|
|
17
|
+
def is_followable?
|
|
18
|
+
true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Specifies if self is followed by a {Follower} object.
|
|
22
|
+
#
|
|
23
|
+
# @return [Boolean]
|
|
24
|
+
def followed_by?(follower)
|
|
25
|
+
raise ArgumentError, "#{follower} is not follower!" unless follower.respond_to?(:is_follower?) && follower.is_follower?
|
|
26
|
+
Socialization.follow_model.follows?(follower, self)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Returns a scope of the {Follower}s following self.
|
|
30
|
+
#
|
|
31
|
+
# @param [Class] klass the {Follower} class to be included in the scope. e.g. `User`
|
|
32
|
+
# @return [Array<Follower, Numeric>] An array of Follower objects or IDs
|
|
33
|
+
def followers(klass, opts = {})
|
|
34
|
+
Socialization.follow_model.followers(self, klass, opts)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
class Base
|
|
3
|
+
def is_likeable?
|
|
4
|
+
false
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module Socialization
|
|
10
|
+
module Likeable
|
|
11
|
+
extend ActiveSupport::Concern
|
|
12
|
+
|
|
13
|
+
included do
|
|
14
|
+
# Specifies if self can be liked.
|
|
15
|
+
#
|
|
16
|
+
# @return [Boolean]
|
|
17
|
+
def is_likeable?
|
|
18
|
+
true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Specifies if self is liked by a {Liker} object.
|
|
22
|
+
#
|
|
23
|
+
# @return [Boolean]
|
|
24
|
+
def liked_by?(liker)
|
|
25
|
+
raise ArgumentError, "#{liker} is not liker!" unless liker.respond_to?(:is_liker?) && liker.is_liker?
|
|
26
|
+
Socialization.like_model.likes?(liker, self)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Returns a scope of the {Liker}s likeing self.
|
|
30
|
+
#
|
|
31
|
+
# @param [Class] klass the {Liker} class to be included in the scope. e.g. `User`.
|
|
32
|
+
# @return [Array<Liker, Numeric>] An array of Liker objects or IDs
|
|
33
|
+
def likers(klass, opts = {})
|
|
34
|
+
Socialization.like_model.likers(self, klass, opts)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|