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,143 @@
|
|
|
1
|
+
module Socialization
|
|
2
|
+
module ActiveRecordStores
|
|
3
|
+
class FollowStore < ActiveRecord::Base
|
|
4
|
+
belongs_to :follower, :polymorphic => true
|
|
5
|
+
belongs_to :followable, :polymorphic => true
|
|
6
|
+
|
|
7
|
+
scope :followed_by, lambda { |follower| where(
|
|
8
|
+
:follower_type => follower.class.table_name.classify,
|
|
9
|
+
:follower_id => follower.id)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
scope :following, lambda { |followable| where(
|
|
13
|
+
:followable_type => followable.class.table_name.classify,
|
|
14
|
+
:followable_id => followable.id)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@@after_create_hook = nil
|
|
18
|
+
@@after_destroy_hook = nil
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
def table_name
|
|
22
|
+
'follows'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def follow!(follower, followable)
|
|
26
|
+
unless follows?(follower, followable)
|
|
27
|
+
self.create! do |follow|
|
|
28
|
+
follow.follower = follower
|
|
29
|
+
follow.followable = followable
|
|
30
|
+
end
|
|
31
|
+
call_after_create_hook(follower, followable)
|
|
32
|
+
follower.touch if [:all, :follower].include?(touch) && follower.respond_to?(:touch)
|
|
33
|
+
followable.touch if [:all, :followable].include?(touch) && followable.respond_to?(:touch)
|
|
34
|
+
true
|
|
35
|
+
else
|
|
36
|
+
false
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def unfollow!(follower, followable)
|
|
41
|
+
if follows?(follower, followable)
|
|
42
|
+
follow_for(follower, followable).destroy_all
|
|
43
|
+
call_after_destroy_hook(follower, followable)
|
|
44
|
+
follower.touch if [:all, :follower].include?(touch) && follower.respond_to?(:touch)
|
|
45
|
+
followable.touch if [:all, :followable].include?(touch) && followable.respond_to?(:touch)
|
|
46
|
+
true
|
|
47
|
+
else
|
|
48
|
+
false
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def follows?(follower, followable)
|
|
53
|
+
!follow_for(follower, followable).empty?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns an ActiveRecord::Relation of all the followers of a certain type that are following followable
|
|
57
|
+
def followers_relation(followable, klass, opts = {})
|
|
58
|
+
rel = klass.where(:id =>
|
|
59
|
+
self.select(:follower_id).
|
|
60
|
+
where(:follower_type => klass.table_name.classify).
|
|
61
|
+
where(:followable_type => followable.class.to_s).
|
|
62
|
+
where(:followable_id => followable.id)
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
if opts[:pluck]
|
|
66
|
+
rel.pluck(opts[:pluck])
|
|
67
|
+
else
|
|
68
|
+
rel
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Returns all the followers of a certain type that are following followable
|
|
73
|
+
def followers(followable, klass, opts = {})
|
|
74
|
+
rel = followers_relation(followable, klass, opts)
|
|
75
|
+
if rel.is_a?(ActiveRecord::Relation)
|
|
76
|
+
rel.all
|
|
77
|
+
else
|
|
78
|
+
rel
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Returns an ActiveRecord::Relation of all the followables of a certain type that are followed by follower
|
|
83
|
+
def followables_relation(follower, klass, opts = {})
|
|
84
|
+
rel = klass.where(:id =>
|
|
85
|
+
self.select(:followable_id).
|
|
86
|
+
where(:followable_type => klass.table_name.classify).
|
|
87
|
+
where(:follower_type => follower.class.to_s).
|
|
88
|
+
where(:follower_id => follower.id)
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
if opts[:pluck]
|
|
92
|
+
rel.pluck(opts[:pluck])
|
|
93
|
+
else
|
|
94
|
+
rel
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Returns all the followables of a certain type that are followed by follower
|
|
99
|
+
def followables(follower, klass, opts = {})
|
|
100
|
+
rel = followables_relation(follower, klass, opts)
|
|
101
|
+
if rel.is_a?(ActiveRecord::Relation)
|
|
102
|
+
rel.all
|
|
103
|
+
else
|
|
104
|
+
rel
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def touch(what = nil)
|
|
109
|
+
if what.nil?
|
|
110
|
+
@touch || false
|
|
111
|
+
else
|
|
112
|
+
raise ArgumentError unless [:all, :follower, :followable, false, nil].include?(what)
|
|
113
|
+
@touch = what
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def after_follow(method)
|
|
118
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
119
|
+
@after_create_hook = method
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def after_unfollow(method)
|
|
123
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
124
|
+
@after_destroy_hook = method
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
private
|
|
128
|
+
def call_after_create_hook(follower, followable)
|
|
129
|
+
self.send(@after_create_hook, follower, followable) if @after_create_hook
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def call_after_destroy_hook(follower, followable)
|
|
133
|
+
self.send(@after_destroy_hook, follower, followable) if @after_destroy_hook
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def follow_for(follower, followable)
|
|
137
|
+
followed_by(follower).following(followable)
|
|
138
|
+
end
|
|
139
|
+
end # class << self
|
|
140
|
+
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
module Socialization
|
|
2
|
+
module ActiveRecordStores
|
|
3
|
+
class LikeStore < ActiveRecord::Base
|
|
4
|
+
belongs_to :liker, :polymorphic => true
|
|
5
|
+
belongs_to :likeable, :polymorphic => true
|
|
6
|
+
|
|
7
|
+
scope :liked_by, lambda { |liker| where(
|
|
8
|
+
:liker_type => liker.class.table_name.classify,
|
|
9
|
+
:liker_id => liker.id)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
scope :liking, lambda { |likeable| where(
|
|
13
|
+
:likeable_type => likeable.class.table_name.classify,
|
|
14
|
+
:likeable_id => likeable.id)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@@after_create_hook = nil
|
|
18
|
+
@@after_destroy_hook = nil
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
def table_name
|
|
22
|
+
'likes'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def like!(liker, likeable)
|
|
26
|
+
unless likes?(liker, likeable)
|
|
27
|
+
self.create! do |like|
|
|
28
|
+
like.liker = liker
|
|
29
|
+
like.likeable = likeable
|
|
30
|
+
end
|
|
31
|
+
call_after_create_hook(liker, likeable)
|
|
32
|
+
liker.touch if [:all, :liker].include?(touch) && liker.respond_to?(:touch)
|
|
33
|
+
likeable.touch if [:all, :likeable].include?(touch) && likeable.respond_to?(:touch)
|
|
34
|
+
true
|
|
35
|
+
else
|
|
36
|
+
false
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def unlike!(liker, likeable)
|
|
41
|
+
if likes?(liker, likeable)
|
|
42
|
+
like_for(liker, likeable).destroy_all
|
|
43
|
+
call_after_destroy_hook(liker, likeable)
|
|
44
|
+
liker.touch if [:all, :liker].include?(touch) && liker.respond_to?(:touch)
|
|
45
|
+
likeable.touch if [:all, :likeable].include?(touch) && likeable.respond_to?(:touch)
|
|
46
|
+
true
|
|
47
|
+
else
|
|
48
|
+
false
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def likes?(liker, likeable)
|
|
53
|
+
!like_for(liker, likeable).empty?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns an ActiveRecord::Relation of all the likers of a certain type that are liking likeable
|
|
57
|
+
def likers_relation(likeable, klass, opts = {})
|
|
58
|
+
rel = klass.where(:id =>
|
|
59
|
+
self.select(:liker_id).
|
|
60
|
+
where(:liker_type => klass.table_name.classify).
|
|
61
|
+
where(:likeable_type => likeable.class.to_s).
|
|
62
|
+
where(:likeable_id => likeable.id)
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
if opts[:pluck]
|
|
66
|
+
rel.pluck(opts[:pluck])
|
|
67
|
+
else
|
|
68
|
+
rel
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Returns all the likers of a certain type that are liking likeable
|
|
73
|
+
def likers(likeable, klass, opts = {})
|
|
74
|
+
rel = likers_relation(likeable, klass, opts)
|
|
75
|
+
if rel.is_a?(ActiveRecord::Relation)
|
|
76
|
+
rel.all
|
|
77
|
+
else
|
|
78
|
+
rel
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Returns an ActiveRecord::Relation of all the likeables of a certain type that are liked by liker
|
|
83
|
+
def likeables_relation(liker, klass, opts = {})
|
|
84
|
+
rel = klass.where(:id =>
|
|
85
|
+
self.select(:likeable_id).
|
|
86
|
+
where(:likeable_type => klass.table_name.classify).
|
|
87
|
+
where(:liker_type => liker.class.to_s).
|
|
88
|
+
where(:liker_id => liker.id)
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
if opts[:pluck]
|
|
92
|
+
rel.pluck(opts[:pluck])
|
|
93
|
+
else
|
|
94
|
+
rel
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Returns all the likeables of a certain type that are liked by liker
|
|
99
|
+
def likeables(liker, klass, opts = {})
|
|
100
|
+
rel = likeables_relation(liker, klass, opts)
|
|
101
|
+
if rel.is_a?(ActiveRecord::Relation)
|
|
102
|
+
rel.all
|
|
103
|
+
else
|
|
104
|
+
rel
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def touch(what = nil)
|
|
109
|
+
if what.nil?
|
|
110
|
+
@touch || false
|
|
111
|
+
else
|
|
112
|
+
raise ArgumentError unless [:all, :liker, :likeable, false, nil].include?(what)
|
|
113
|
+
@touch = what
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def after_like(method)
|
|
118
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
119
|
+
@after_create_hook = method
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def after_unlike(method)
|
|
123
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
124
|
+
@after_destroy_hook = method
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
private
|
|
128
|
+
def call_after_create_hook(liker, likeable)
|
|
129
|
+
self.send(@after_create_hook, liker, likeable) if @after_create_hook
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def call_after_destroy_hook(liker, likeable)
|
|
133
|
+
self.send(@after_destroy_hook, liker, likeable) if @after_destroy_hook
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def like_for(liker, likeable)
|
|
137
|
+
liked_by(liker).liking( likeable)
|
|
138
|
+
end
|
|
139
|
+
end # class << self
|
|
140
|
+
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
module Socialization
|
|
2
|
+
module ActiveRecordStores
|
|
3
|
+
class MentionStore < ActiveRecord::Base
|
|
4
|
+
belongs_to :mentioner, :polymorphic => true
|
|
5
|
+
belongs_to :mentionable, :polymorphic => true
|
|
6
|
+
|
|
7
|
+
scope :mentioned_by, lambda { |mentioner| where(
|
|
8
|
+
:mentioner_type => mentioner.class.table_name.classify,
|
|
9
|
+
:mentioner_id => mentioner.id)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
scope :mentioning, lambda { |mentionable| where(
|
|
13
|
+
:mentionable_type => mentionable.class.table_name.classify,
|
|
14
|
+
:mentionable_id => mentionable.id)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@@after_create_hook = nil
|
|
18
|
+
@@after_destroy_hook = nil
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
def table_name
|
|
22
|
+
'mentions'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def mention!(mentioner, mentionable)
|
|
26
|
+
unless mentions?(mentioner, mentionable)
|
|
27
|
+
self.create! do |mention|
|
|
28
|
+
mention.mentioner = mentioner
|
|
29
|
+
mention.mentionable = mentionable
|
|
30
|
+
end
|
|
31
|
+
call_after_create_hook(mentioner, mentionable)
|
|
32
|
+
mentioner.touch if [:all, :mentioner].include?(touch) && mentioner.respond_to?(:touch)
|
|
33
|
+
mentionable.touch if [:all, :mentionable].include?(touch) && mentionable.respond_to?(:touch)
|
|
34
|
+
true
|
|
35
|
+
else
|
|
36
|
+
false
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def unmention!(mentioner, mentionable)
|
|
41
|
+
if mentions?(mentioner, mentionable)
|
|
42
|
+
mention_for(mentioner, mentionable).destroy_all
|
|
43
|
+
call_after_destroy_hook(mentioner, mentionable)
|
|
44
|
+
mentioner.touch if [:all, :mentioner].include?(touch) && mentioner.respond_to?(:touch)
|
|
45
|
+
mentionable.touch if [:all, :mentionable].include?(touch) && mentionable.respond_to?(:touch)
|
|
46
|
+
true
|
|
47
|
+
else
|
|
48
|
+
false
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def mentions?(mentioner, mentionable)
|
|
53
|
+
!mention_for(mentioner, mentionable).empty?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns an ActiveRecord::Relation of all the mentioners of a certain type that are mentioning mentionable
|
|
57
|
+
def mentioners_relation(mentionable, klass, opts = {})
|
|
58
|
+
rel = klass.where(:id =>
|
|
59
|
+
self.select(:mentioner_id).
|
|
60
|
+
where(:mentioner_type => klass.table_name.classify).
|
|
61
|
+
where(:mentionable_type => mentionable.class.to_s).
|
|
62
|
+
where(:mentionable_id => mentionable.id)
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
if opts[:pluck]
|
|
66
|
+
rel.pluck(opts[:pluck])
|
|
67
|
+
else
|
|
68
|
+
rel
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Returns all the mentioners of a certain type that are mentioning mentionable
|
|
73
|
+
def mentioners(mentionable, klass, opts = {})
|
|
74
|
+
rel = mentioners_relation(mentionable, klass, opts)
|
|
75
|
+
if rel.is_a?(ActiveRecord::Relation)
|
|
76
|
+
rel.all
|
|
77
|
+
else
|
|
78
|
+
rel
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Returns an ActiveRecord::Relation of all the mentionables of a certain type that are mentioned by mentioner
|
|
83
|
+
def mentionables_relation(mentioner, klass, opts = {})
|
|
84
|
+
rel = klass.where(:id =>
|
|
85
|
+
self.select(:mentionable_id).
|
|
86
|
+
where(:mentionable_type => klass.table_name.classify).
|
|
87
|
+
where(:mentioner_type => mentioner.class.to_s).
|
|
88
|
+
where(:mentioner_id => mentioner.id)
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
if opts[:pluck]
|
|
92
|
+
rel.pluck(opts[:pluck])
|
|
93
|
+
else
|
|
94
|
+
rel
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Returns all the mentionables of a certain type that are mentioned by mentioner
|
|
99
|
+
def mentionables(mentioner, klass, opts = {})
|
|
100
|
+
rel = mentionables_relation(mentioner, klass, opts)
|
|
101
|
+
if rel.is_a?(ActiveRecord::Relation)
|
|
102
|
+
rel.all
|
|
103
|
+
else
|
|
104
|
+
rel
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def touch(what = nil)
|
|
109
|
+
if what.nil?
|
|
110
|
+
@touch || false
|
|
111
|
+
else
|
|
112
|
+
raise ArgumentError unless [:all, :mentioner, :mentionable, false, nil].include?(what)
|
|
113
|
+
@touch = what
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def after_mention(method)
|
|
118
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
119
|
+
@after_create_hook = method
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def after_unmention(method)
|
|
123
|
+
raise ArgumentError unless method.is_a?(Symbol) || method.nil?
|
|
124
|
+
@after_destroy_hook = method
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
private
|
|
128
|
+
def call_after_create_hook(mentioner, mentionable)
|
|
129
|
+
self.send(@after_create_hook, mentioner, mentionable) if @after_create_hook
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def call_after_destroy_hook(mentioner, mentionable)
|
|
133
|
+
self.send(@after_destroy_hook, mentioner, mentionable) if @after_destroy_hook
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def mention_for(mentioner, mentionable)
|
|
137
|
+
mentioned_by(mentioner).mentioning(mentionable)
|
|
138
|
+
end
|
|
139
|
+
end # class << self
|
|
140
|
+
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|