mention_system 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.empty +0 -0
- data/.gitignore +15 -0
- data/.keep +0 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +23 -0
- data/Appraisals +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +170 -0
- data/Rakefile +8 -0
- data/gemfiles/.empty +0 -0
- data/gemfiles/.gitignore +0 -0
- data/gemfiles/.keep +0 -0
- data/gemfiles/rails4.1.gemfile +7 -0
- data/gemfiles/rails4.2.gemfile +7 -0
- data/lib/.empty +0 -0
- data/lib/.gitignore +0 -0
- data/lib/.keep +0 -0
- data/lib/generators/.empty +0 -0
- data/lib/generators/.gitignore +0 -0
- data/lib/generators/.keep +0 -0
- data/lib/generators/mention_system/.empty +0 -0
- data/lib/generators/mention_system/.gitignore +0 -0
- data/lib/generators/mention_system/.keep +0 -0
- data/lib/generators/mention_system/mention_system_generator.rb +46 -0
- data/lib/generators/mention_system/templates/.empty +0 -0
- data/lib/generators/mention_system/templates/.gitignore +0 -0
- data/lib/generators/mention_system/templates/.keep +0 -0
- data/lib/generators/mention_system/templates/migration.rb +47 -0
- data/lib/mention_system.rb +46 -0
- data/lib/mention_system/.empty +0 -0
- data/lib/mention_system/.gitignore +0 -0
- data/lib/mention_system/.keep +0 -0
- data/lib/mention_system/mention.rb +155 -0
- data/lib/mention_system/mention_processor.rb +141 -0
- data/lib/mention_system/mentionee.rb +58 -0
- data/lib/mention_system/mentioner.rb +88 -0
- data/lib/mention_system/version.rb +12 -0
- data/mention_system.gemspec +31 -0
- data/spec/.empty +0 -0
- data/spec/.gitignore +0 -0
- data/spec/.keep +0 -0
- data/spec/db/.empty +0 -0
- data/spec/db/.gitignore +0 -0
- data/spec/db/.keep +0 -0
- data/spec/db/migrate/.empty +0 -0
- data/spec/db/migrate/.gitignore +0 -0
- data/spec/db/migrate/.keep +0 -0
- data/spec/db/migrate/20140926000000_create_mentions.rb +47 -0
- data/spec/db/migrate/20140926000005_create_dummy_mentioners.rb +22 -0
- data/spec/db/migrate/20140926000010_create_dummy_mentionees.rb +22 -0
- data/spec/mention_system/.empty +0 -0
- data/spec/mention_system/.gitignore +0 -0
- data/spec/mention_system/.keep +0 -0
- data/spec/mention_system/mention_processor_spec.rb +155 -0
- data/spec/mention_system/mention_spec.rb +177 -0
- data/spec/mention_system/mentionee_spec.rb +69 -0
- data/spec/mention_system/mentioner_spec.rb +96 -0
- data/spec/spec_helper.rb +116 -0
- data/spec/support/.empty +0 -0
- data/spec/support/.gitignore +0 -0
- data/spec/support/.keep +0 -0
- data/spec/support/active_record.rb +12 -0
- data/spec/support/shoulda_matchers.rb +2 -0
- metadata +240 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a9832b3de5374b194dbe23671741890a0be2c9e6
|
4
|
+
data.tar.gz: 63d03b4497243bf782891a3f12afd7e9b0fe6be4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3c7bc689c331e4a13baa3f8b2cb15a745d6c4e5835980869c5fd0d4a0b6419feee28500068f7cd313e09124f59af1de3191f8258a6cc53a6e016934e7d45de08
|
7
|
+
data.tar.gz: 776a9a2276c94eda158771b95de5d601851e9101132d66ea137ca200604949b3c578378202b3845c5fd4665ef92205b1c68350d3563d91a8d1279c687eb5792c
|
data/.empty
ADDED
File without changes
|
data/.gitignore
ADDED
data/.keep
ADDED
File without changes
|
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
mention_system
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.2.1
|
data/.travis.yml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
language:
|
2
|
+
- ruby
|
3
|
+
|
4
|
+
rvm:
|
5
|
+
- 2.0.0
|
6
|
+
- 2.1.3
|
7
|
+
- 2.2.1
|
8
|
+
|
9
|
+
gemfile:
|
10
|
+
- gemfiles/rails4.1.gemfile
|
11
|
+
- gemfiles/rails4.2.gemfile
|
12
|
+
|
13
|
+
install:
|
14
|
+
- "travis_retry bundle install"
|
15
|
+
|
16
|
+
before_script:
|
17
|
+
|
18
|
+
script:
|
19
|
+
- "bundle exec rake"
|
20
|
+
|
21
|
+
branches:
|
22
|
+
only:
|
23
|
+
- master
|
data/Appraisals
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Pablo Martin Viva
|
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,170 @@
|
|
1
|
+
# MentionSystem
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/pmviva/mention_system.png?branch=master)](https://travis-ci.org/pmviva/mention_system)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/mention_system.svg)](http://badge.fury.io/rb/mention_system)
|
5
|
+
|
6
|
+
An active record mention system developed using ruby on rails 4.1 applying domain driven design and test driven development principles.
|
7
|
+
|
8
|
+
This gem is heavily influenced by cmer/socialization.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'mention_system'
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
$ bundle
|
22
|
+
```
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
$ gem install mention_system
|
28
|
+
```
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
### Run the generator
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
$ rails g mention_system
|
36
|
+
```
|
37
|
+
|
38
|
+
Let's suppose for a moment that you have a blog application and a Post can mention a User or several User models.
|
39
|
+
The post model becomes the mentioner and the user model becomes the mentionee.
|
40
|
+
|
41
|
+
### User object
|
42
|
+
```ruby
|
43
|
+
class User < ActiveRecord::Base
|
44
|
+
act_as_mentionee
|
45
|
+
|
46
|
+
validates :username, { presence: true, uniqueness: true }
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
### Post object
|
51
|
+
```ruby
|
52
|
+
class Post < ActiveRecord::Base
|
53
|
+
act_as_mentioner
|
54
|
+
|
55
|
+
validates :content, presence: true
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
### Mentionee object methods
|
60
|
+
```ruby
|
61
|
+
user.is_mentionee? # returns true
|
62
|
+
|
63
|
+
user.mentioned_by?(post) # returns true if post mentions the user object, false otherwise
|
64
|
+
|
65
|
+
user.mentioners_by(Post) # returns a scope of MentionSystem::Mention join model that belongs to the user object and belongs to mentioner objects of type Post
|
66
|
+
```
|
67
|
+
|
68
|
+
|
69
|
+
### Mentioner object methods
|
70
|
+
```ruby
|
71
|
+
post.is_mentioner? # returns true
|
72
|
+
|
73
|
+
post.mention(user) # Creates an instance of MentionSystem::Mention join model associating the post object and the user object, returns true if succeded, false otherwise
|
74
|
+
|
75
|
+
post.unmention(user) # Destroys an instance of MentionSystem::Mention join model that associates the post object and the user object, returns true if succeded, false otherwise
|
76
|
+
|
77
|
+
post.toggle_mention(user) # Mentions / unmentions the user
|
78
|
+
|
79
|
+
post.mentions?(user) # returns true if the post object mentions the user object, false otherwise
|
80
|
+
|
81
|
+
post.mentionees_by(User) # returns a scope of MentionSystem::Mention join model that belongs to the post object and belongs to mentionee objects of type User
|
82
|
+
```
|
83
|
+
|
84
|
+
### Mention processors
|
85
|
+
Mention processors are objects in charge of computing mentions between mentioner objects and mentionee objects.
|
86
|
+
The framework provides a base mention processor class that the developer should subclass.
|
87
|
+
Mention processors provide after / before callbacks to hook custom behavior before and after a mention is computed.
|
88
|
+
|
89
|
+
Let's suppose we want to parse a post content and process mentions in the form of "@username". We first define a custom mention processor instructing how to compute a post content and how to retrieve a collection of users by the handles mentioned in the post content.
|
90
|
+
|
91
|
+
### CustomMentionProcessor object
|
92
|
+
```ruby
|
93
|
+
class CustomMentionProcessor < MentionSystem::MentionProcessor
|
94
|
+
###
|
95
|
+
# This method returns the content used to parse mentions from the mentioner object, in this case is post's content
|
96
|
+
###
|
97
|
+
def extract_mentioner_content(post)
|
98
|
+
post.content
|
99
|
+
end
|
100
|
+
|
101
|
+
###
|
102
|
+
# This method should return a collection (must respond to each) of mentionee objects for a given set of handles
|
103
|
+
# In our case will be a collection of user objects
|
104
|
+
###
|
105
|
+
def find_mentionees_by_handles(*handles)
|
106
|
+
User.where(username: handles)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
When we call
|
112
|
+
```ruby
|
113
|
+
user1 = User.create(username: "test1")
|
114
|
+
user2 = User.create(username: "test2")
|
115
|
+
post = Post.create(content: "Post content mentioning @test1 and @test2")
|
116
|
+
|
117
|
+
m = CustomMentionProcessor.new
|
118
|
+
m.process_mentions(post)
|
119
|
+
```
|
120
|
+
|
121
|
+
It will process a mention between "post" and "user1" and also a mention between "post" and "user2".
|
122
|
+
|
123
|
+
### Mention processor callbacks
|
124
|
+
Suppose we want to validate if a user can be mentioned before a mention is processed, we can register a before callback in the mention processor.
|
125
|
+
Now lets suppose we want to send a notification email when a mention is given to a user, we can register an after callback in the mention processor.
|
126
|
+
|
127
|
+
Lets see an example of both:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
m = CustomMentionProcessor.new
|
131
|
+
|
132
|
+
m.add_before_callback Proc.new { |post, user| user.mentions_allowed? }
|
133
|
+
m.add_after_callback Proc.new { |post, user| UserMailer.notify_mention(post, user) }
|
134
|
+
|
135
|
+
m.process_mentions(post)
|
136
|
+
```
|
137
|
+
|
138
|
+
Now when the mention processor process the mentions in the post content, it should validate first if the user is allowed to mention and after the mention is processed an email sent notifying the mention.
|
139
|
+
|
140
|
+
You can register several callbacks and they will be called in order.
|
141
|
+
* When a before callback return false it will not call any further before callback, nor process the mention nor will call any after callbacks.
|
142
|
+
* When a mention could not be processed none of the after callbacks will be called.
|
143
|
+
* When an after callback returns false it will not call any further after callback.
|
144
|
+
|
145
|
+
You can override the prefix used to parse mentions, it defaults to "@" but you can change to any prefix you like, for example "#", so that mention processors can recognize #test1 and #test2 instead of @user1 and @user2.
|
146
|
+
|
147
|
+
To do that you need to override the mention_prefix method in the mention processor.
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
class CustomMentionProcessor < MentionSystem::MentionProcessor
|
151
|
+
private:
|
152
|
+
###
|
153
|
+
# Defines the mention prefix used to parse mentions, defaults "@"
|
154
|
+
###
|
155
|
+
def mention_prefix
|
156
|
+
"#"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
```
|
160
|
+
|
161
|
+
For more information read the [api documentation](http://rubydoc.info/gems/mention_system).
|
162
|
+
|
163
|
+
## Contributing
|
164
|
+
|
165
|
+
1. Fork it ( https://github.com/pmviva/mention_system/fork )
|
166
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
167
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
168
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
169
|
+
5. Create a new Pull Request
|
170
|
+
|
data/Rakefile
ADDED
data/gemfiles/.empty
ADDED
File without changes
|
data/gemfiles/.gitignore
ADDED
File without changes
|
data/gemfiles/.keep
ADDED
File without changes
|
data/lib/.empty
ADDED
File without changes
|
data/lib/.gitignore
ADDED
File without changes
|
data/lib/.keep
ADDED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rails/generators/migration'
|
2
|
+
require 'rails/generators/active_record'
|
3
|
+
|
4
|
+
###
|
5
|
+
# MentionSystemGenerator class
|
6
|
+
#
|
7
|
+
# This class generates the mention model migration in mention system
|
8
|
+
###
|
9
|
+
class MentionSystemGenerator < Rails::Generators::Base
|
10
|
+
###
|
11
|
+
# Includes Rails::Generators::Migration
|
12
|
+
###
|
13
|
+
include Rails::Generators::Migration
|
14
|
+
|
15
|
+
###
|
16
|
+
# Generator description definition
|
17
|
+
###
|
18
|
+
desc "Generates a migration for the Mention model"
|
19
|
+
|
20
|
+
###
|
21
|
+
# Retrieves the source root
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
###
|
25
|
+
def self.source_root
|
26
|
+
@source_root ||= File.dirname(__FILE__) + '/templates'
|
27
|
+
end
|
28
|
+
|
29
|
+
###
|
30
|
+
# Retrieves the next migration number
|
31
|
+
#
|
32
|
+
# @path [String] path - the path to calculate the next migration number
|
33
|
+
# @return [String]
|
34
|
+
###
|
35
|
+
def self.next_migration_number(path)
|
36
|
+
ActiveRecord::Generators::Base.next_migration_number(path)
|
37
|
+
end
|
38
|
+
|
39
|
+
###
|
40
|
+
# Generates the migration
|
41
|
+
###
|
42
|
+
def generate_migration
|
43
|
+
migration_template 'migration.rb', 'db/migrate/create_mentions.rb'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,47 @@
|
|
1
|
+
###
|
2
|
+
# CreateMentions class
|
3
|
+
#
|
4
|
+
# This class defines the create mentions migration in mention system
|
5
|
+
###
|
6
|
+
class CreateMentions < ActiveRecord::Migration
|
7
|
+
###
|
8
|
+
# Changes the database
|
9
|
+
###
|
10
|
+
def change
|
11
|
+
###
|
12
|
+
# Mentions table creation
|
13
|
+
###
|
14
|
+
create_table :mentions do |t|
|
15
|
+
###
|
16
|
+
# Mentionee id field and mentionee type field definition
|
17
|
+
###
|
18
|
+
t.references :mentionee, polymorphic: true
|
19
|
+
|
20
|
+
###
|
21
|
+
# Mentioner id fiel and mentioner type field definition
|
22
|
+
###
|
23
|
+
t.references :mentioner, polymorphic: true
|
24
|
+
|
25
|
+
###
|
26
|
+
# Timestamps fields definition
|
27
|
+
###
|
28
|
+
t.timestamps null: false
|
29
|
+
end
|
30
|
+
|
31
|
+
###
|
32
|
+
# Mentions table mentionee id field and mentionee type field index addition
|
33
|
+
###
|
34
|
+
add_index :mentions, [:mentionee_id, :mentionee_type], name: "mentions_mentionee_idx"
|
35
|
+
|
36
|
+
###
|
37
|
+
# Mentions table mentioner id field and mentioner type field index addition
|
38
|
+
###
|
39
|
+
add_index :mentions, [:mentioner_id, :mentioner_type], name: "mentions_mentioner_idx"
|
40
|
+
|
41
|
+
###
|
42
|
+
# Mentions table mentionee id field and mentionee type field and mentioner id field and mentioner type field unique index addition
|
43
|
+
###
|
44
|
+
add_index :mentions, [:mentionee_id, :mentionee_type, :mentioner_id, :mentioner_type], name: "mentions_mentionee_mentioner_idx", unique: true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'mention_system/mention'
|
2
|
+
require 'mention_system/mention_processor'
|
3
|
+
require 'mention_system/mentionee'
|
4
|
+
require 'mention_system/mentioner'
|
5
|
+
|
6
|
+
###
|
7
|
+
# MentionSystem module
|
8
|
+
#
|
9
|
+
# This module defines common behavior in mention system
|
10
|
+
###
|
11
|
+
module MentionSystem
|
12
|
+
###
|
13
|
+
# Specifies if self can be mentioned by {Mentioner} objects
|
14
|
+
#
|
15
|
+
# @return [Boolean]
|
16
|
+
###
|
17
|
+
def is_mentionee?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
###
|
22
|
+
# Specifies if self can mention {Mentionee} objects
|
23
|
+
#
|
24
|
+
# @return [Boolean]
|
25
|
+
###
|
26
|
+
def is_mentioner?
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
###
|
31
|
+
# Instructs self to act as mentionee
|
32
|
+
###
|
33
|
+
def act_as_mentionee
|
34
|
+
include Mentionee
|
35
|
+
end
|
36
|
+
|
37
|
+
###
|
38
|
+
# Instructs self to act as mentioner
|
39
|
+
###
|
40
|
+
def act_as_mentioner
|
41
|
+
include Mentioner
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
ActiveRecord::Base.extend MentionSystem
|
46
|
+
|