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.
Files changed (144) hide show
  1. data/.gitignore +5 -1
  2. data/CHANGELOG.md +41 -0
  3. data/README.md +246 -0
  4. data/demo/{demo_app/.gitignore → .gitignore} +0 -0
  5. data/demo/{demo_app/Gemfile → Gemfile} +1 -1
  6. data/demo/{demo_app/README.rdoc → README.rdoc} +0 -0
  7. data/demo/{demo_app/Rakefile → Rakefile} +0 -0
  8. data/demo/{demo_app/app → app}/assets/images/rails.png +0 -0
  9. data/demo/{demo_app/app → app}/assets/javascripts/application.js +0 -0
  10. data/demo/{demo_app/app → app}/assets/stylesheets/application.css +0 -0
  11. data/demo/{demo_app/app → app}/controllers/application_controller.rb +0 -0
  12. data/demo/{demo_app/app → app}/helpers/application_helper.rb +0 -0
  13. data/demo/{demo_app/app → app}/mailers/.gitkeep +0 -0
  14. data/demo/{demo_app/app → app}/models/.gitkeep +0 -0
  15. data/demo/{demo_app/app → app}/models/celebrity.rb +0 -0
  16. data/demo/{demo_app/app → app}/models/comment.rb +0 -0
  17. data/demo/app/models/follow.rb +2 -0
  18. data/demo/app/models/like.rb +2 -0
  19. data/demo/app/models/mention.rb +2 -0
  20. data/demo/{demo_app/app → app}/models/movie.rb +0 -0
  21. data/demo/{demo_app/app → app}/models/user.rb +0 -0
  22. data/demo/{demo_app/app → app}/views/layouts/application.html.erb +0 -0
  23. data/demo/{demo_app/config.ru → config.ru} +0 -0
  24. data/demo/{demo_app/config → config}/application.rb +0 -0
  25. data/demo/{demo_app/config → config}/boot.rb +0 -0
  26. data/demo/{demo_app/config → config}/database.yml +0 -0
  27. data/demo/{demo_app/config → config}/environment.rb +0 -0
  28. data/demo/{demo_app/config → config}/environments/development.rb +0 -0
  29. data/demo/{demo_app/config → config}/environments/production.rb +0 -0
  30. data/demo/{demo_app/config → config}/environments/test.rb +0 -0
  31. data/demo/{demo_app/config → config}/initializers/backtrace_silencers.rb +0 -0
  32. data/demo/{demo_app/config → config}/initializers/inflections.rb +0 -0
  33. data/demo/{demo_app/config → config}/initializers/mime_types.rb +0 -0
  34. data/demo/{demo_app/config → config}/initializers/secret_token.rb +0 -0
  35. data/demo/{demo_app/config → config}/initializers/session_store.rb +1 -1
  36. data/demo/{demo_app/config → config}/initializers/wrap_parameters.rb +1 -1
  37. data/demo/{demo_app/config → config}/locales/en.yml +0 -0
  38. data/demo/{demo_app/config → config}/routes.rb +0 -0
  39. data/demo/{demo_app/db → db}/migrate/20120115051222_create_users.rb +0 -0
  40. data/demo/{demo_app/db → db}/migrate/20120115051234_create_movies.rb +0 -0
  41. data/demo/{demo_app/db → db}/migrate/20120115051255_create_celebrities.rb +0 -0
  42. data/demo/{demo_app/db → db}/migrate/20120115054646_create_follows.rb +0 -0
  43. data/demo/{demo_app/db → db}/migrate/20120115054647_create_likes.rb +0 -0
  44. data/demo/{demo_app/db → db}/migrate/20120221200644_create_mentions.rb +0 -0
  45. data/demo/{demo_app/db → db}/migrate/20120221202703_create_comments.rb +0 -0
  46. data/demo/{demo_app/db → db}/schema.rb +0 -1
  47. data/demo/{demo_app/db → db}/seeds.rb +0 -0
  48. data/demo/{demo_app/lib → lib}/assets/.gitkeep +0 -0
  49. data/demo/{demo_app/lib → lib}/tasks/.gitkeep +0 -0
  50. data/demo/{demo_app/public → public}/404.html +0 -0
  51. data/demo/{demo_app/public → public}/422.html +0 -0
  52. data/demo/{demo_app/public → public}/500.html +0 -0
  53. data/demo/{demo_app/public → public}/favicon.ico +0 -0
  54. data/demo/{demo_app/public → public}/index.html +0 -0
  55. data/demo/{demo_app/public → public}/robots.txt +0 -0
  56. data/demo/{demo_app/script → script}/rails +0 -0
  57. data/demo/{demo_app/test → test}/fixtures/.gitkeep +0 -0
  58. data/demo/{demo_app/test → test}/fixtures/celebrities.yml +0 -0
  59. data/demo/{demo_app/test → test}/fixtures/movies.yml +0 -0
  60. data/demo/{demo_app/test → test}/fixtures/users.yml +0 -0
  61. data/demo/{demo_app/test → test}/functional/.gitkeep +0 -0
  62. data/demo/{demo_app/test → test}/integration/.gitkeep +0 -0
  63. data/demo/{demo_app/test → test}/performance/browsing_test.rb +0 -0
  64. data/demo/{demo_app/test → test}/test_helper.rb +0 -0
  65. data/demo/{demo_app/test → test}/unit/.gitkeep +0 -0
  66. data/demo/{demo_app/test → test}/unit/celebrity_test.rb +0 -0
  67. data/demo/{demo_app/test → test}/unit/movie_test.rb +0 -0
  68. data/demo/{demo_app/test → test}/unit/user_test.rb +0 -0
  69. data/demo/{demo_app/vendor → vendor}/assets/javascripts/.gitkeep +0 -0
  70. data/demo/{demo_app/vendor → vendor}/assets/stylesheets/.gitkeep +0 -0
  71. data/demo/{demo_app/vendor → vendor}/plugins/.gitkeep +0 -0
  72. data/lib/generators/socialization/socialization_generator.rb +20 -9
  73. data/{generators/socialization/templates → lib/generators/socialization/templates/active_record}/migration_follows.rb +0 -0
  74. data/{generators/socialization/templates → lib/generators/socialization/templates/active_record}/migration_likes.rb +0 -0
  75. data/{generators/socialization/templates → lib/generators/socialization/templates/active_record}/migration_mentions.rb +0 -0
  76. data/lib/generators/socialization/templates/active_record/model_follow.rb +2 -0
  77. data/lib/generators/socialization/templates/active_record/model_like.rb +2 -0
  78. data/lib/generators/socialization/templates/active_record/model_mention.rb +2 -0
  79. data/lib/socialization.rb +3 -5
  80. data/lib/socialization/actors/follower.rb +74 -0
  81. data/lib/socialization/actors/liker.rb +74 -0
  82. data/lib/socialization/actors/mentioner.rb +74 -0
  83. data/lib/socialization/acts_as_helpers.rb +43 -0
  84. data/lib/socialization/config.rb +45 -0
  85. data/lib/socialization/helpers/string.rb +17 -0
  86. data/lib/socialization/stores/active_record/follow_store.rb +143 -0
  87. data/lib/socialization/stores/active_record/like_store.rb +143 -0
  88. data/lib/socialization/stores/active_record/mention_store.rb +143 -0
  89. data/lib/socialization/stores/redis/base.rb +8 -0
  90. data/lib/socialization/stores/redis/config.rb +11 -0
  91. data/lib/socialization/stores/redis/follow_store.rb +126 -0
  92. data/lib/socialization/stores/redis/like_store.rb +126 -0
  93. data/lib/socialization/stores/redis/mention_store.rb +126 -0
  94. data/lib/socialization/version.rb +1 -1
  95. data/lib/socialization/victims/followable.rb +38 -0
  96. data/lib/socialization/victims/likeable.rb +38 -0
  97. data/lib/socialization/victims/mentionable.rb +38 -0
  98. data/socialization.gemspec +3 -3
  99. data/test/actors/follower_test.rb +74 -0
  100. data/test/actors/liker_test.rb +74 -0
  101. data/test/actors/mentioner_test.rb +74 -0
  102. data/test/stores/active_record/follow_store_test.rb +121 -0
  103. data/test/stores/active_record/like_store_test.rb +121 -0
  104. data/test/stores/active_record/mention_store_test.rb +121 -0
  105. data/test/stores/redis/config_test.rb +30 -0
  106. data/test/stores/redis/follow_store_test.rb +153 -0
  107. data/test/stores/redis/like_store_test.rb +153 -0
  108. data/test/stores/redis/mention_store_test.rb +153 -0
  109. data/test/string_test.rb +13 -0
  110. data/test/test_helper.rb +70 -12
  111. data/test/victims/followable_test.rb +34 -0
  112. data/test/victims/likeable_test.rb +34 -0
  113. data/test/victims/mentionable_test.rb +34 -0
  114. data/test/world_test.rb +80 -69
  115. metadata +261 -176
  116. data/README.rdoc +0 -186
  117. data/demo/demo_app/app/models/follow.rb +0 -3
  118. data/demo/demo_app/app/models/like.rb +0 -3
  119. data/demo/demo_app/app/models/mention.rb +0 -3
  120. data/demo/demo_app/doc/README_FOR_APP +0 -2
  121. data/gemfiles/activerecord30.gemfile +0 -6
  122. data/gemfiles/activerecord30.gemfile.lock +0 -23
  123. data/gemfiles/activerecord31.gemfile +0 -6
  124. data/gemfiles/activerecord31.gemfile.lock +0 -25
  125. data/gemfiles/activerecord32.gemfile +0 -6
  126. data/gemfiles/activerecord32.gemfile.lock +0 -25
  127. data/generators/socialization/USAGE +0 -1
  128. data/generators/socialization/socialization_generator.rb +0 -15
  129. data/generators/socialization/templates/model_follow.rb +0 -3
  130. data/generators/socialization/templates/model_like.rb +0 -3
  131. data/generators/socialization/templates/model_mention.rb +0 -3
  132. data/lib/socialization/follow_store.rb +0 -14
  133. data/lib/socialization/followable.rb +0 -34
  134. data/lib/socialization/follower.rb +0 -50
  135. data/lib/socialization/hello.rb +0 -53
  136. data/lib/socialization/like_store.rb +0 -14
  137. data/lib/socialization/likeable.rb +0 -34
  138. data/lib/socialization/liker.rb +0 -54
  139. data/lib/socialization/mention_store.rb +0 -14
  140. data/lib/socialization/mentionable.rb +0 -36
  141. data/lib/socialization/mentioner.rb +0 -54
  142. data/test/follow_test.rb +0 -125
  143. data/test/like_test.rb +0 -125
  144. 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
@@ -1,3 +1,3 @@
1
1
  module Socialization
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0.beta"
3
3
  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