interest 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +26 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +329 -0
  7. data/Rakefile +2 -0
  8. data/interest.gemspec +29 -0
  9. data/lib/generators/interest_generator.rb +18 -0
  10. data/lib/generators/templates/migrations/blockings.rb +14 -0
  11. data/lib/generators/templates/migrations/followings.rb +15 -0
  12. data/lib/generators/templates/models/blocking.rb +3 -0
  13. data/lib/generators/templates/models/following.rb +4 -0
  14. data/lib/interest.rb +49 -0
  15. data/lib/interest/base.rb +49 -0
  16. data/lib/interest/blockable.rb +25 -0
  17. data/lib/interest/blockable/blockee.rb +40 -0
  18. data/lib/interest/blockable/blocker.rb +69 -0
  19. data/lib/interest/blockable/blocking.rb +48 -0
  20. data/lib/interest/blockable/exceptions.rb +12 -0
  21. data/lib/interest/definition.rb +45 -0
  22. data/lib/interest/exception.rb +10 -0
  23. data/lib/interest/follow_requestable.rb +25 -0
  24. data/lib/interest/follow_requestable/exceptions.rb +12 -0
  25. data/lib/interest/follow_requestable/follow_request.rb +45 -0
  26. data/lib/interest/follow_requestable/follow_requestee.rb +45 -0
  27. data/lib/interest/follow_requestable/follow_requester.rb +92 -0
  28. data/lib/interest/followable.rb +25 -0
  29. data/lib/interest/followable/exceptions.rb +12 -0
  30. data/lib/interest/followable/followee.rb +41 -0
  31. data/lib/interest/followable/follower.rb +68 -0
  32. data/lib/interest/followable/following.rb +62 -0
  33. data/lib/interest/utils.rb +29 -0
  34. data/lib/interest/version.rb +3 -0
  35. data/spec/blockable_spec.rb +127 -0
  36. data/spec/database.yml.example +3 -0
  37. data/spec/follow_requestable_spec.rb +126 -0
  38. data/spec/followable_spec.rb +171 -0
  39. data/spec/models/blocking_spec.rb +42 -0
  40. data/spec/models/following_spec.rb +120 -0
  41. data/spec/spec_helper.rb +103 -0
  42. data/spec/support/database.rb +10 -0
  43. data/spec/support/models/blockable_user.rb +8 -0
  44. data/spec/support/models/blocking.rb +4 -0
  45. data/spec/support/models/collection.rb +6 -0
  46. data/spec/support/models/follow_requestable_and_blockable_user.rb +8 -0
  47. data/spec/support/models/follow_requestable_user.rb +9 -0
  48. data/spec/support/models/followable_and_blockable_user.rb +9 -0
  49. data/spec/support/models/followable_user.rb +8 -0
  50. data/spec/support/models/following.rb +4 -0
  51. data/spec/support/models/stuff.rb +6 -0
  52. data/spec/support/schema.rb +26 -0
  53. metadata +211 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fc82c4e1059269fa9b2883ec3e3b44a5abeb3b13
4
+ data.tar.gz: 3261ddd2763d276aeb65f99d2aed75385a0870a8
5
+ SHA512:
6
+ metadata.gz: d0d24030c45c3fa07c7cecf3936324f7b24215bb55485982582568856fa4253d9602fe454cfa8fdb05bc0935923e0069acf6a586d97c9800dbc773fce7825385
7
+ data.tar.gz: f0de0016b106f52a0baa34f6d78ae2e115d4f84d3cdb83c1de75427a90c84288e097e7f715a3ea2612f99582af6497db3c60fb0347debfa08d13d6a3047f19f9
data/.gitignore ADDED
@@ -0,0 +1,26 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+
24
+ vendor/bundle
25
+ spec/database.yml
26
+ spec/*.sqlite3
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in interest.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 tatat
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,329 @@
1
+ # Interest
2
+
3
+ a gem to follow, follow request and block between any ActiveRecord models.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'interest'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install interest
18
+
19
+ ### Post installation
20
+
21
+ #### Install migrations and models
22
+
23
+ ```
24
+ bin/rails generate interest
25
+ ```
26
+
27
+ #### Migrate
28
+
29
+ ```
30
+ bin/rake db:migrate
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ### Setup
36
+
37
+ Create User and Blog model as one example.
38
+
39
+ ```ruby
40
+ class User < ActiveRecord::Base
41
+ interest
42
+ end
43
+
44
+ class Blog < ActiveRecord::Base
45
+ interest
46
+ end
47
+
48
+ user = User.create!
49
+ blog = Blog.create!
50
+ ```
51
+
52
+ ### Follow
53
+
54
+ To follow,
55
+
56
+ ```ruby
57
+ following = user.follow!(blog)
58
+ ```
59
+
60
+ returns `Following` or raises `Interest::Followable::Rejected`.
61
+
62
+ Otherwise,
63
+
64
+ ```ruby
65
+ following = user.follow(blog)
66
+ ```
67
+
68
+ returns `Following` or `nil`.
69
+
70
+ Returned `Following` is the following.
71
+
72
+ ```ruby
73
+ following.follower == user # => true
74
+ following.followee == blog # => true
75
+ following.status # => "accepted"
76
+ ```
77
+
78
+ To unfollow,
79
+
80
+ ```ruby
81
+ user.unfollow(blog)
82
+ ```
83
+
84
+ To check whether the user is following the blog or not,
85
+
86
+ ```ruby
87
+ user.following?(blog)
88
+ ```
89
+
90
+ or
91
+
92
+ ```ruby
93
+ blog.followed_by?(user)
94
+ ```
95
+
96
+ #### Associations
97
+
98
+ ```ruby
99
+ user.following_relationships.of(Blog)
100
+ ```
101
+
102
+ and
103
+
104
+ ```ruby
105
+ blog.follower_relationships.of(User)
106
+ ```
107
+
108
+ returns `ActiveRecord::Associations::CollectionProxy` for `Following` belongs to `User` and `Blog`.
109
+
110
+ ```ruby
111
+ user.following_blogs
112
+ ```
113
+
114
+ returns `ActiveRecord::Associations::CollectionProxy` for `Blog`.
115
+
116
+ ```ruby
117
+ blog.follower_users
118
+ ```
119
+
120
+ returns `ActiveRecord::Associations::CollectionProxy` for `User`.
121
+
122
+ "blogs" and "users" part of the above are conditional on a class.
123
+
124
+ e.g.
125
+
126
+ ```ruby
127
+ other_user = OtherUser.create!
128
+ user.follow(other_user) # follows OtherUser
129
+ ```
130
+
131
+ then
132
+
133
+ ```ruby
134
+ user.following_other_users
135
+ ```
136
+
137
+ (It's just like `"ClassName".underscore.pluralize`)
138
+
139
+ ### Follow request
140
+
141
+ To request to follow,
142
+
143
+ ```ruby
144
+ following = user.request_to_follow!(blog)
145
+ ```
146
+
147
+ returns `Following` or raises `Interest::FollowRequestable::Rejected`.
148
+
149
+ Otherwise,
150
+
151
+ ```ruby
152
+ following = user.request_to_follow!(blog)
153
+ ```
154
+
155
+ returns `Following` or `nil`.
156
+
157
+ Returned `Following` is the following.
158
+
159
+ ```ruby
160
+ following.status # => "pending"
161
+ ```
162
+
163
+ To cancel request to follow,
164
+
165
+ ```ruby
166
+ user.cancel_request_to_follow(blog)
167
+ ```
168
+
169
+ To check whether the user has requested to follow the blog or not,
170
+
171
+ ```ruby
172
+ user.has_requested_to_follow?(blog)
173
+ ```
174
+
175
+ or
176
+
177
+ ```ruby
178
+ blog.has_been_requested_to_follow?(user)
179
+ ```
180
+
181
+ To accept request to follow, call `accept!` of `Following`
182
+
183
+ ```ruby
184
+ following = blog.incoming_follow_requests.of(User).find(id) # `Following.find(id)' is more simply.
185
+ following.accept!
186
+ ```
187
+
188
+ #### Associations
189
+
190
+ ```ruby
191
+ user.outgoing_follow_requests.of(Blog)
192
+ ```
193
+
194
+ and
195
+
196
+ ```ruby
197
+ blog.incoming_follow_requests.of(User)
198
+ ```
199
+
200
+ returns `ActiveRecord::Associations::CollectionProxy` for `Following` belongs to `User` and `Blog`
201
+
202
+ ```ruby
203
+ user.follow_requestee_blogs
204
+ ```
205
+
206
+ returns `ActiveRecord::Associations::CollectionProxy` for `Blog`
207
+
208
+ ```ruby
209
+ blog.follow_requester_users
210
+ ```
211
+
212
+ returns `ActiveRecord::Associations::CollectionProxy` for `User`
213
+
214
+ #### Note
215
+
216
+ `follow!` and `follow` methods don't check whether the user is required to request to follow the blog, so you should check it yourself.
217
+
218
+ In this case, you need to define (override) `requires_request_to_follow?` on `Blog` first.
219
+
220
+ ```ruby
221
+ class Blog < ActiveRecord::Base
222
+ # ...
223
+
224
+ def requires_request_to_follow?(follower)
225
+ true # or something
226
+ end
227
+ end
228
+ ```
229
+
230
+ Then, like the following
231
+
232
+ ```ruby
233
+ if user.required_request_to_follow?(blog)
234
+ user.request_to_follow(blog)
235
+ else
236
+ user.follow(blog)
237
+ end
238
+ ```
239
+
240
+ or
241
+
242
+ ```ruby
243
+ result = user.follow_or_request_to_follow!(blog)
244
+
245
+ if result.followed?
246
+ # when the user followed the blog
247
+ elsif result.requested_to_follow?
248
+ # when the user requested to follow the blog
249
+ end
250
+ ```
251
+
252
+ ### Block
253
+
254
+ To block,
255
+
256
+ ```ruby
257
+ blocking = blog.block!(user)
258
+ ```
259
+
260
+ returns `Blocking` or raises `Interest::Blockable::Rejected`.
261
+
262
+ Otherwise,
263
+
264
+ ```ruby
265
+ blocking = blog.block!(user)
266
+ ```
267
+
268
+ returns `Blocking` or `nil`
269
+
270
+ Returned `Blocking` is the following
271
+
272
+ ```ruby
273
+ blocking.blocker == blog # => true
274
+ blocking.blockee == user # => true
275
+ ```
276
+
277
+ Blocking destroys their folow and follow request relationships if they have.
278
+
279
+ To unblock,
280
+
281
+ ```ruby
282
+ blog.unblock(user)
283
+ ```
284
+
285
+ To check whether the blog is blocking the user or not,
286
+
287
+ ```ruby
288
+ blog.blocking?(user)
289
+ ```
290
+
291
+ or
292
+
293
+ ```ruby
294
+ user.blocked_by?(blog)
295
+ ```
296
+
297
+ #### Associations
298
+
299
+ ```ruby
300
+ blog.blocking_relationships.of(User)
301
+ ```
302
+
303
+ and
304
+
305
+ ```ruby
306
+ user.blocker_relationships.of(Blog)
307
+ ```
308
+
309
+ returns `ActiveRecord::Associations::CollectionProxy` for `Blocking` belongs to `Blog` and `User`
310
+
311
+ ```ruby
312
+ blog.blocking_users
313
+ ```
314
+
315
+ returns `ActiveRecord::Associations::CollectionProxy` for `User`
316
+
317
+ ```ruby
318
+ user.blocker_blogs
319
+ ```
320
+
321
+ returns `ActiveRecord::Associations::CollectionProxy` for `Blog`
322
+
323
+ ## Contributing
324
+
325
+ 1. Fork it ( https://github.com/conol/interest/fork )
326
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
327
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
328
+ 4. Push to the branch (`git push origin my-new-feature`)
329
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/interest.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'interest/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "interest"
8
+ spec.version = Interest::VERSION
9
+ spec.authors = ["tatat"]
10
+ spec.email = ["ioiioioloo@gmail.com"]
11
+ spec.summary = %q{Follow, follow request and block with ActiveRecord.}
12
+ spec.description = %q{A gem to follow, follow request and block between any ActiveRecord models.}
13
+ spec.homepage = "https://github.com/conol/interest"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "activesupport", "~> 4.0"
22
+ spec.add_dependency "activerecord", "~> 4.0"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.6"
25
+ spec.add_development_dependency "rake", "~> 10.3"
26
+ spec.add_development_dependency "sqlite3", "~> 1.3"
27
+ spec.add_development_dependency "rspec", "~> 3.0"
28
+ spec.add_development_dependency "rspec-collection_matchers", "~> 1"
29
+ end
@@ -0,0 +1,18 @@
1
+ require "rails/generators"
2
+ require "rails/generators/active_record"
3
+
4
+ class InterestGenerator < Rails::Generators::Base
5
+ include ActiveRecord::Generators::Migration
6
+
7
+ source_root File.expand_path("templates", File.dirname(__FILE__))
8
+
9
+ def create_migration_file
10
+ migration_template "migrations/followings.rb", "db/migrate/interest_followings_migration.rb"
11
+ migration_template "migrations/blockings.rb", "db/migrate/interest_blockings_migration.rb"
12
+ end
13
+
14
+ def create_model
15
+ copy_file "models/following.rb", "app/models/following.rb"
16
+ copy_file "models/blocking.rb", "app/models/blocking.rb"
17
+ end
18
+ end