mention_system 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.empty +0 -0
  3. data/.gitignore +15 -0
  4. data/.keep +0 -0
  5. data/.rspec +2 -0
  6. data/.ruby-gemset +1 -0
  7. data/.ruby-version +1 -0
  8. data/.travis.yml +23 -0
  9. data/Appraisals +7 -0
  10. data/Gemfile +4 -0
  11. data/LICENSE.txt +22 -0
  12. data/README.md +170 -0
  13. data/Rakefile +8 -0
  14. data/gemfiles/.empty +0 -0
  15. data/gemfiles/.gitignore +0 -0
  16. data/gemfiles/.keep +0 -0
  17. data/gemfiles/rails4.1.gemfile +7 -0
  18. data/gemfiles/rails4.2.gemfile +7 -0
  19. data/lib/.empty +0 -0
  20. data/lib/.gitignore +0 -0
  21. data/lib/.keep +0 -0
  22. data/lib/generators/.empty +0 -0
  23. data/lib/generators/.gitignore +0 -0
  24. data/lib/generators/.keep +0 -0
  25. data/lib/generators/mention_system/.empty +0 -0
  26. data/lib/generators/mention_system/.gitignore +0 -0
  27. data/lib/generators/mention_system/.keep +0 -0
  28. data/lib/generators/mention_system/mention_system_generator.rb +46 -0
  29. data/lib/generators/mention_system/templates/.empty +0 -0
  30. data/lib/generators/mention_system/templates/.gitignore +0 -0
  31. data/lib/generators/mention_system/templates/.keep +0 -0
  32. data/lib/generators/mention_system/templates/migration.rb +47 -0
  33. data/lib/mention_system.rb +46 -0
  34. data/lib/mention_system/.empty +0 -0
  35. data/lib/mention_system/.gitignore +0 -0
  36. data/lib/mention_system/.keep +0 -0
  37. data/lib/mention_system/mention.rb +155 -0
  38. data/lib/mention_system/mention_processor.rb +141 -0
  39. data/lib/mention_system/mentionee.rb +58 -0
  40. data/lib/mention_system/mentioner.rb +88 -0
  41. data/lib/mention_system/version.rb +12 -0
  42. data/mention_system.gemspec +31 -0
  43. data/spec/.empty +0 -0
  44. data/spec/.gitignore +0 -0
  45. data/spec/.keep +0 -0
  46. data/spec/db/.empty +0 -0
  47. data/spec/db/.gitignore +0 -0
  48. data/spec/db/.keep +0 -0
  49. data/spec/db/migrate/.empty +0 -0
  50. data/spec/db/migrate/.gitignore +0 -0
  51. data/spec/db/migrate/.keep +0 -0
  52. data/spec/db/migrate/20140926000000_create_mentions.rb +47 -0
  53. data/spec/db/migrate/20140926000005_create_dummy_mentioners.rb +22 -0
  54. data/spec/db/migrate/20140926000010_create_dummy_mentionees.rb +22 -0
  55. data/spec/mention_system/.empty +0 -0
  56. data/spec/mention_system/.gitignore +0 -0
  57. data/spec/mention_system/.keep +0 -0
  58. data/spec/mention_system/mention_processor_spec.rb +155 -0
  59. data/spec/mention_system/mention_spec.rb +177 -0
  60. data/spec/mention_system/mentionee_spec.rb +69 -0
  61. data/spec/mention_system/mentioner_spec.rb +96 -0
  62. data/spec/spec_helper.rb +116 -0
  63. data/spec/support/.empty +0 -0
  64. data/spec/support/.gitignore +0 -0
  65. data/spec/support/.keep +0 -0
  66. data/spec/support/active_record.rb +12 -0
  67. data/spec/support/shoulda_matchers.rb +2 -0
  68. 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
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /gemfiles/*.lock
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
data/.keep ADDED
File without changes
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
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
@@ -0,0 +1,7 @@
1
+ appraise "rails4.1" do
2
+ gem "rails", "4.1.10"
3
+ end
4
+
5
+ appraise "rails4.2" do
6
+ gem "rails", "4.2.1"
7
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mention_system.gemspec
4
+ gemspec
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
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :default => [:spec]
4
+ desc 'run Rspec specs'
5
+ task :spec do
6
+ sh 'rspec spec'
7
+ end
8
+
data/gemfiles/.empty ADDED
File without changes
File without changes
data/gemfiles/.keep ADDED
File without changes
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "4.1.10"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "4.2.1"
6
+
7
+ gemspec :path => "../"
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
@@ -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
+