socialization 0.4.0 → 0.5.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/README.rdoc
DELETED
@@ -1,186 +0,0 @@
|
|
1
|
-
= Socialization
|
2
|
-
|
3
|
-
Socialization is a Ruby Gem that allows any model to Follow, Like and/or Mention any other model. This is accomplished through double polymorphic relationships, but you don't need to know that since all the complexity is hidden from you.
|
4
|
-
|
5
|
-
The Follow feature is similar to Twitter's Follow. For example, John follows Jane. Unlike Facebook's "friendship", Follow is a one-way concept. The fact that John follows Jane doesn't mean that Jane follows John.
|
6
|
-
|
7
|
-
The Like feature works just like a Facebook Like. For example, John likes Pulp Fiction.
|
8
|
-
|
9
|
-
The Mention feature was written with Facebook mentions in mind. For example, John mentions Jane in a comment. Typically, Jane would be highlighted in the comment user interface and possibly notified that John mentioned her. This Facebook feature is occasionally called Tagging, although tagging is generally something {entirely different}[http://en.wikipedia.org/wiki/Tag_(metadata)].
|
10
|
-
|
11
|
-
{<img src="https://secure.travis-ci.org/cmer/socialization.png" />}[http://travis-ci.org/cmer/socialization]
|
12
|
-
|
13
|
-
== Installation
|
14
|
-
|
15
|
-
=== Rails 3
|
16
|
-
|
17
|
-
Add the gem to the gemfile:
|
18
|
-
gem "socialization"
|
19
|
-
|
20
|
-
Run the generator:
|
21
|
-
rails generate socialization -s
|
22
|
-
|
23
|
-
This will generate three migration files and threww models named Follow, Like and Mention. You may delete the Follow, Like or Mention model and migration if you don't need that functionality in your application.
|
24
|
-
|
25
|
-
=== Rails 2.3.x Support
|
26
|
-
|
27
|
-
This gem requires Rails 3 or better. Sorry!
|
28
|
-
|
29
|
-
== Usage
|
30
|
-
|
31
|
-
=== Setup
|
32
|
-
|
33
|
-
Allow a model to be followed:
|
34
|
-
class Celebrity < ActiveRecord::Base
|
35
|
-
...
|
36
|
-
acts_as_followable
|
37
|
-
...
|
38
|
-
end
|
39
|
-
|
40
|
-
Allow a model to be a follower:
|
41
|
-
class User < ActiveRecord::Base
|
42
|
-
...
|
43
|
-
acts_as_follower
|
44
|
-
...
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
|
-
Allow a model to be liked:
|
49
|
-
class Movie < ActiveRecord::Base
|
50
|
-
...
|
51
|
-
acts_as_likeable
|
52
|
-
...
|
53
|
-
end
|
54
|
-
|
55
|
-
Allow a model to like:
|
56
|
-
class User < ActiveRecord::Base
|
57
|
-
...
|
58
|
-
acts_as_liker
|
59
|
-
...
|
60
|
-
end
|
61
|
-
|
62
|
-
Allow a model to be mentioned:
|
63
|
-
class User < ActiveRecord::Base
|
64
|
-
...
|
65
|
-
acts_as_mentionable
|
66
|
-
...
|
67
|
-
end
|
68
|
-
|
69
|
-
Allow a model to mention:
|
70
|
-
class Comment < ActiveRecord::Base
|
71
|
-
...
|
72
|
-
acts_as_mentioner
|
73
|
-
...
|
74
|
-
end
|
75
|
-
|
76
|
-
Or a more complex case where users can like and follow each other:
|
77
|
-
class User < ActiveRecord::Base
|
78
|
-
...
|
79
|
-
acts_as_follower
|
80
|
-
acts_as_followable
|
81
|
-
acts_as_liker
|
82
|
-
acts_as_likeable
|
83
|
-
acts_as_mentionable
|
84
|
-
...
|
85
|
-
end
|
86
|
-
|
87
|
-
---
|
88
|
-
|
89
|
-
=== acts_as_follower Methods
|
90
|
-
|
91
|
-
Follow something
|
92
|
-
user.follow!(celebrity)
|
93
|
-
|
94
|
-
Stop following
|
95
|
-
user.unfollow!(celebrity)
|
96
|
-
|
97
|
-
Is following?
|
98
|
-
user.follows?(celebrity)
|
99
|
-
|
100
|
-
---
|
101
|
-
|
102
|
-
=== acts_as_followable Methods
|
103
|
-
|
104
|
-
Find out if an objects follows
|
105
|
-
celebrity.followed_by?(user)
|
106
|
-
|
107
|
-
All followers
|
108
|
-
celebrity.followers(User)
|
109
|
-
|
110
|
-
---
|
111
|
-
|
112
|
-
=== acts_as_liker Methods
|
113
|
-
|
114
|
-
Like something
|
115
|
-
user.like!(movie)
|
116
|
-
|
117
|
-
Stop liking
|
118
|
-
user.unlike!(movie)
|
119
|
-
|
120
|
-
Likes?
|
121
|
-
user.likes?(movie)
|
122
|
-
|
123
|
-
---
|
124
|
-
|
125
|
-
=== acts_as_likeable Methods
|
126
|
-
|
127
|
-
Find out if an objects likes
|
128
|
-
movie.liked_by?(user)
|
129
|
-
|
130
|
-
All likers
|
131
|
-
movie.likers(User)
|
132
|
-
|
133
|
-
=== acts_as_mentioner Methods
|
134
|
-
|
135
|
-
<b>Note that a "mentioner" is the object containing the mention and not necessarily the actor. For example, John mentions Jane in a comment. The mentioner is the comment object, NOT John.</b>
|
136
|
-
|
137
|
-
Mention something
|
138
|
-
comment.mention!(user)
|
139
|
-
|
140
|
-
Remove mention
|
141
|
-
comment.unmention!(user)
|
142
|
-
|
143
|
-
Mentions?
|
144
|
-
comment.mentions?(user)
|
145
|
-
|
146
|
-
---
|
147
|
-
|
148
|
-
=== acts_as_mentionable Methods
|
149
|
-
|
150
|
-
Find out if an objects mentions
|
151
|
-
user.mentioned_by?(comment)
|
152
|
-
|
153
|
-
All mentioners
|
154
|
-
user.mentioners(Comment)
|
155
|
-
|
156
|
-
---
|
157
|
-
|
158
|
-
== Demo App
|
159
|
-
|
160
|
-
For your convenience, I have added a demo app in demo/demo_app. It does not have a web UI, but you can play with Socialization in the Rails console. It should also help you figure out hown to use Socialization in the Real World.
|
161
|
-
|
162
|
-
To use the demo app:
|
163
|
-
|
164
|
-
$ cd demo/demo_app
|
165
|
-
$ bundle
|
166
|
-
$ rake db:migrate
|
167
|
-
$ rake db:seed
|
168
|
-
$ rails console
|
169
|
-
|
170
|
-
|
171
|
-
== Note on Patches/Pull Requests
|
172
|
-
|
173
|
-
* Fork the project.
|
174
|
-
* Make your feature addition or bug fix.
|
175
|
-
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
176
|
-
* Send me a pull request. Bonus points for topic branches.
|
177
|
-
|
178
|
-
== Similar Projects
|
179
|
-
|
180
|
-
acts_as_follower[https://github.com/tcocca/acts_as_follower] is a similar project that I only discovered when I was 95% finished writing the first version of Socialization. I initially intended to name this project acts_as_follower only to find out the name was taken. You might want to check it out as well so see which one suits your needs better. Socialization is simpler, supports "Likes" and "Mentions" and easilly extendable; acts_as_follower has more "Follow" features, however.
|
181
|
-
|
182
|
-
|
183
|
-
== Copyright
|
184
|
-
|
185
|
-
Copyright (c) 2012 Carl Mercier -- Released under the MIT license.
|
186
|
-
|
@@ -1,23 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
activemodel (3.0.11)
|
5
|
-
activesupport (= 3.0.11)
|
6
|
-
builder (~> 2.1.2)
|
7
|
-
i18n (~> 0.5.0)
|
8
|
-
activerecord (3.0.11)
|
9
|
-
activemodel (= 3.0.11)
|
10
|
-
activesupport (= 3.0.11)
|
11
|
-
arel (~> 2.0.10)
|
12
|
-
tzinfo (~> 0.3.23)
|
13
|
-
activesupport (3.0.11)
|
14
|
-
arel (2.0.10)
|
15
|
-
builder (2.1.2)
|
16
|
-
i18n (0.5.0)
|
17
|
-
tzinfo (0.3.31)
|
18
|
-
|
19
|
-
PLATFORMS
|
20
|
-
ruby
|
21
|
-
|
22
|
-
DEPENDENCIES
|
23
|
-
activerecord (~> 3.0.10)
|
@@ -1,25 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
activemodel (3.1.3)
|
5
|
-
activesupport (= 3.1.3)
|
6
|
-
builder (~> 3.0.0)
|
7
|
-
i18n (~> 0.6)
|
8
|
-
activerecord (3.1.3)
|
9
|
-
activemodel (= 3.1.3)
|
10
|
-
activesupport (= 3.1.3)
|
11
|
-
arel (~> 2.2.1)
|
12
|
-
tzinfo (~> 0.3.29)
|
13
|
-
activesupport (3.1.3)
|
14
|
-
multi_json (~> 1.0)
|
15
|
-
arel (2.2.2)
|
16
|
-
builder (3.0.0)
|
17
|
-
i18n (0.6.0)
|
18
|
-
multi_json (1.1.0)
|
19
|
-
tzinfo (0.3.31)
|
20
|
-
|
21
|
-
PLATFORMS
|
22
|
-
ruby
|
23
|
-
|
24
|
-
DEPENDENCIES
|
25
|
-
activerecord (~> 3.1.1)
|
@@ -1,25 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
activemodel (3.2.1)
|
5
|
-
activesupport (= 3.2.1)
|
6
|
-
builder (~> 3.0.0)
|
7
|
-
activerecord (3.2.1)
|
8
|
-
activemodel (= 3.2.1)
|
9
|
-
activesupport (= 3.2.1)
|
10
|
-
arel (~> 3.0.0)
|
11
|
-
tzinfo (~> 0.3.29)
|
12
|
-
activesupport (3.2.1)
|
13
|
-
i18n (~> 0.6)
|
14
|
-
multi_json (~> 1.0)
|
15
|
-
arel (3.0.1)
|
16
|
-
builder (3.0.0)
|
17
|
-
i18n (0.6.0)
|
18
|
-
multi_json (1.1.0)
|
19
|
-
tzinfo (0.3.31)
|
20
|
-
|
21
|
-
PLATFORMS
|
22
|
-
ruby
|
23
|
-
|
24
|
-
DEPENDENCIES
|
25
|
-
activerecord (~> 3.2.1)
|
@@ -1 +0,0 @@
|
|
1
|
-
Generates the Follow, Like and Mention models as well as their migrations.
|
@@ -1,15 +0,0 @@
|
|
1
|
-
class SocializationGenerator < Rails::Generator::Base
|
2
|
-
def manifest
|
3
|
-
record do |m|
|
4
|
-
m.template 'model_follow.rb', 'app/models/follow.rb'
|
5
|
-
m.template 'model_like.rb', 'app/models/like.rb'
|
6
|
-
m.template 'model_mention.rb', 'app/models/mention.rb'
|
7
|
-
|
8
|
-
m.migration_template 'migration_follows.rb', 'db/migrate', :migration_file_name => 'create_follows'
|
9
|
-
sleep 1 # force unique migration timestamp
|
10
|
-
m.migration_template 'migration_likes.rb', 'db/migrate', :migration_file_name => 'create_likes'
|
11
|
-
sleep 1 # force unique migration timestamp
|
12
|
-
m.migration_template 'migration_mentions.rb', 'db/migrate', :migration_file_name => 'create_mentions'
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module Socialization
|
2
|
-
module FollowStore
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
included do
|
6
|
-
belongs_to :follower, :polymorphic => true
|
7
|
-
belongs_to :followable, :polymorphic => true
|
8
|
-
|
9
|
-
validates_uniqueness_of :followable_type, :scope => [:followable_id, :follower_type, :follower_id], :message => 'You cannot follow the same thing twice.'
|
10
|
-
|
11
|
-
def self.human_attribute_name(*args); ''; end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,34 +0,0 @@
|
|
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
|
-
# A following is the Follow record of the follower following self.
|
15
|
-
has_many :followings, :as => :followable, :dependent => :destroy, :class_name => 'Follow'
|
16
|
-
|
17
|
-
def is_followable?
|
18
|
-
true
|
19
|
-
end
|
20
|
-
|
21
|
-
def followed_by?(follower)
|
22
|
-
raise ArgumentError, "#{follower} is not a follower!" unless follower.is_follower?
|
23
|
-
!self.followings.where(:follower_type => follower.class.to_s, :follower_id => follower.id).empty?
|
24
|
-
end
|
25
|
-
|
26
|
-
def followers(klass)
|
27
|
-
klass = klass.to_s.singularize.camelize.constantize unless klass.is_a?(Class)
|
28
|
-
klass.joins("INNER JOIN follows ON follows.follower_id = #{klass.to_s.tableize}.id AND follows.follower_type = '#{klass.to_s}'").
|
29
|
-
where("follows.followable_type = '#{self.class.to_s}'").
|
30
|
-
where("follows.followable_id = #{self.id}")
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
class Base
|
3
|
-
def is_follower?
|
4
|
-
false
|
5
|
-
end
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
module Socialization
|
10
|
-
module Follower
|
11
|
-
extend ActiveSupport::Concern
|
12
|
-
|
13
|
-
included do
|
14
|
-
# A follow is the Follow record of self following a followable record.
|
15
|
-
has_many :follows, :as => :follower, :dependent => :destroy, :class_name => 'Follow'
|
16
|
-
|
17
|
-
def is_follower?
|
18
|
-
true
|
19
|
-
end
|
20
|
-
|
21
|
-
def follow!(followable)
|
22
|
-
raise ArgumentError, "#{followable} is not followable!" unless followable.is_followable?
|
23
|
-
raise ArgumentError, "#{self} cannot follow itself!" unless self != followable
|
24
|
-
Follow.create!({ :follower => self, :followable => followable }, :without_protection => true)
|
25
|
-
end
|
26
|
-
|
27
|
-
def unfollow!(followable)
|
28
|
-
ff = followable.followings.where(:follower_type => self.class.to_s, :follower_id => self.id)
|
29
|
-
unless ff.empty?
|
30
|
-
ff.each { |f| f.destroy }
|
31
|
-
else
|
32
|
-
raise ActiveRecord::RecordNotFound
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def follows?(followable)
|
37
|
-
raise ArgumentError, "#{followable} is not followable!" unless followable.is_followable?
|
38
|
-
!self.follows.where(:followable_type => followable.class.to_s, :followable_id => followable.id).empty?
|
39
|
-
end
|
40
|
-
|
41
|
-
def followees(klass)
|
42
|
-
klass = klass.to_s.singularize.camelize.constantize unless klass.is_a?(Class)
|
43
|
-
klass.joins("INNER JOIN follows ON follows.followable_id = #{klass.to_s.tableize}.id AND follows.followable_type = '#{klass.to_s}'").
|
44
|
-
where("follows.follower_type = '#{self.class.to_s}'").
|
45
|
-
where("follows.follower_id = #{self.id}")
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|