my_feeds 0.0.1
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 +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +174 -0
- data/Rakefile +1 -0
- data/lib/my_feeds.rb +7 -0
- data/lib/my_feeds/eater.rb +9 -0
- data/lib/my_feeds/feeder.rb +23 -0
- data/lib/my_feeds/identify.rb +36 -0
- data/lib/my_feeds/version.rb +3 -0
- data/lib/rails/generators/my_feeds/likes_generator.rb +29 -0
- data/lib/rails/generators/my_feeds_generator.rb +28 -0
- data/lib/rails/generators/templates/like_model.rb +7 -0
- data/lib/rails/generators/templates/likes_migration.rb +18 -0
- data/lib/rails/generators/templates/migration.rb +18 -0
- data/lib/rails/generators/templates/model.rb +10 -0
- data/my_feeds.gemspec +23 -0
- metadata +95 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 jjy
|
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,174 @@
|
|
1
|
+
# MyFeeds
|
2
|
+
|
3
|
+
-------------------------------------
|
4
|
+
Help you implement feeds / timeline in rails application.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
------------------------------------
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'my_feeds'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install my_feeds
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
------------------------------------
|
24
|
+
|
25
|
+
####before usage
|
26
|
+
my_feeds need three type model at least
|
27
|
+
|
28
|
+
`feeder`, `eater` and associate model
|
29
|
+
|
30
|
+
feeder publish feeds
|
31
|
+
|
32
|
+
eater receive publish
|
33
|
+
|
34
|
+
and associate model create a relation between feeder and eater
|
35
|
+
|
36
|
+
yes, like subscribe and publish
|
37
|
+
|
38
|
+
####feed model
|
39
|
+
feed model is what feeder published and eater subscribed, you can customize it.
|
40
|
+
|
41
|
+
`rails generate my_feeds`
|
42
|
+
|
43
|
+
####associate model
|
44
|
+
|
45
|
+
`rails generate my_feeds:likes`
|
46
|
+
#####use own associate model
|
47
|
+
you can also use your own associate model.
|
48
|
+
|
49
|
+
just make sure your model have a polymorphic field for feeder.
|
50
|
+
|
51
|
+
and
|
52
|
+
```
|
53
|
+
class YourModel < ActiveRecord::Base
|
54
|
+
include MyFeeds::Identify #make sure include this module
|
55
|
+
self.feed_polymorphic_name = :xxx #and set this, in this case is xxx, same with polymorphic belongs_to
|
56
|
+
|
57
|
+
belongs_to :xxx, polymorphic: true
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
####feeder
|
62
|
+
|
63
|
+
include MyFeeds::Feeder in your model which will as feed source
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
class User < ActiveRecord::Base
|
67
|
+
...
|
68
|
+
include MyFeeds::Feeder
|
69
|
+
...
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
now `User` get a method `define_feed_event`
|
74
|
+
|
75
|
+
use `define_feed_event` define your feed_event
|
76
|
+
```ruby
|
77
|
+
class User < ActiveRecord::Base
|
78
|
+
...
|
79
|
+
include MyFeeds::Feeder
|
80
|
+
|
81
|
+
define_feed_event :hahahaha
|
82
|
+
define_feed_event :kakakaka
|
83
|
+
...
|
84
|
+
end
|
85
|
+
|
86
|
+
#in you rails console
|
87
|
+
user = User.create ...
|
88
|
+
|
89
|
+
#user get a method hahahaha...
|
90
|
+
#will create 3 feeds
|
91
|
+
user.hahahaha
|
92
|
+
user.hahahaha
|
93
|
+
user.hahahaha
|
94
|
+
|
95
|
+
#you can use source_feeds associate fetch your source feeds
|
96
|
+
user.source_feeds.count #=> 3
|
97
|
+
|
98
|
+
#or scoped version
|
99
|
+
user.hahahaha_feeds.count #=> 3
|
100
|
+
user.kakakaka_feeds.count #=> 0
|
101
|
+
|
102
|
+
#you can pass extra arguments to feed_event method, but must match feed model attributes
|
103
|
+
user.hahahaha target_id: another_user.id, target_type: another_user.class
|
104
|
+
|
105
|
+
user.source_feeds.last.target_id #=> another_user.id
|
106
|
+
|
107
|
+
#you can also passed arguments with define_feed_event, then arguments will be default
|
108
|
+
...
|
109
|
+
define_feed_event :hahahaha, target_type: User
|
110
|
+
...
|
111
|
+
|
112
|
+
user.hahahaha target_id: another_user.id
|
113
|
+
user.source_feeds.last.target_type #=> User
|
114
|
+
```
|
115
|
+
|
116
|
+
####eater
|
117
|
+
include MyFeeds::Eater in your model which will as feed receiver
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
class User < ActiveRecord::Base
|
121
|
+
...
|
122
|
+
include MyFeeds::Eater
|
123
|
+
has_many :likes #a eater must have associate with feeder
|
124
|
+
|
125
|
+
def feeds
|
126
|
+
#eater have method feeds_for, pass associate and return feeds
|
127
|
+
feeds_for likes
|
128
|
+
end
|
129
|
+
...
|
130
|
+
end
|
131
|
+
|
132
|
+
##sample
|
133
|
+
#create relation
|
134
|
+
u = User.create
|
135
|
+
like = u.likes.new
|
136
|
+
like.likeable = another_user
|
137
|
+
like.save
|
138
|
+
like = u.likes.new
|
139
|
+
like.likeable = Post.find ...
|
140
|
+
like.save
|
141
|
+
u.feeds #=> you get feeds
|
142
|
+
|
143
|
+
|
144
|
+
##feeds with scope??
|
145
|
+
class User < ActiveRecord::Base
|
146
|
+
...
|
147
|
+
include MyFeeds::Eater
|
148
|
+
has_many :likes #a eater must have associate with feeder
|
149
|
+
|
150
|
+
def feeds
|
151
|
+
#eater have method feeds_for, pass associate and return feeds
|
152
|
+
feeds_for likes
|
153
|
+
end
|
154
|
+
|
155
|
+
def teams_feeds
|
156
|
+
feeds_for likes.where(likeable_type: Team)
|
157
|
+
end
|
158
|
+
|
159
|
+
def users_posts_feeds
|
160
|
+
feeds_for(likes.where likeable_type: User).where(target_type: Post)
|
161
|
+
end
|
162
|
+
...
|
163
|
+
end
|
164
|
+
```
|
165
|
+
|
166
|
+
## Contributing
|
167
|
+
|
168
|
+
-------------------
|
169
|
+
|
170
|
+
1. Fork it
|
171
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
172
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
173
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
174
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/my_feeds.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module MyFeeds
|
2
|
+
module Feeder
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
has_many :source_feeds, class_name: Feed.to_s, as: :source, dependent: :destroy
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def define_feed_event event, conditions = {}
|
11
|
+
conditions.freeze
|
12
|
+
define_method(event) do |options = {}|
|
13
|
+
attributes = {source_type: self.class.to_s, source_id: self.id, event: event}.merge!(conditions).merge! options
|
14
|
+
Feed.create attributes
|
15
|
+
end
|
16
|
+
|
17
|
+
define_method("#{event}_feeds") do
|
18
|
+
source_feeds.where({event: event}.merge! conditions)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module MyFeeds
|
2
|
+
module Identify
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
before_save :save_feed_identify
|
7
|
+
class_attribute :feed_polymorphic_name
|
8
|
+
self.feed_polymorphic_name = self == Feed ? :source : default_feed_polymorphic_name
|
9
|
+
delegate :default_feed_polymorphic_name, :polymorphic_identify_column, :polymorphic_id_column, :polymorphic_type_column, to: :"self.class"
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
def save_feed_identify
|
14
|
+
instance_eval %Q{self.#{polymorphic_identify_column} = "#\{#{polymorphic_id_column}.to_s\}@#\{#{polymorphic_type_column}.to_s.underscore\}"}
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
module ClassMethods
|
19
|
+
def default_feed_polymorphic_name
|
20
|
+
self.to_s.underscore
|
21
|
+
end
|
22
|
+
|
23
|
+
def polymorphic_identify_column
|
24
|
+
:"#{feed_polymorphic_name}_identify"
|
25
|
+
end
|
26
|
+
|
27
|
+
def polymorphic_id_column
|
28
|
+
:"#{feed_polymorphic_name}_id"
|
29
|
+
end
|
30
|
+
|
31
|
+
def polymorphic_type_column
|
32
|
+
:"#{feed_polymorphic_name}_type"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module MyFeeds
|
2
|
+
module Generators
|
3
|
+
class LikesGenerator < Rails::Generators::Base
|
4
|
+
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
|
7
|
+
def self.source_root
|
8
|
+
@source_root ||= File.join(File.dirname(__FILE__), '../templates')
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_migration_file
|
12
|
+
migration_template 'likes_migration.rb', 'db/migrate/likes_migration.rb'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.next_migration_number(dirname)
|
16
|
+
if ActiveRecord::Base.timestamped_migrations
|
17
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
18
|
+
else
|
19
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_model
|
24
|
+
template "like_model.rb", File.join('app/models', "like.rb")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module MyFeeds
|
2
|
+
module Generators
|
3
|
+
class MyFeedsGenerator < Rails::Generators::Base
|
4
|
+
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
|
7
|
+
def self.source_root
|
8
|
+
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_migration_file
|
12
|
+
migration_template 'migration.rb', 'db/migrate/my_feeds_migration.rb'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.next_migration_number(dirname)
|
16
|
+
if ActiveRecord::Base.timestamped_migrations
|
17
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
18
|
+
else
|
19
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_model
|
24
|
+
template "model.rb", File.join('app/models', "feed.rb")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class LikesMigration < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :likes do |t|
|
4
|
+
#this table must have xxx_identify, xxx_id, xxx_type 3 columns
|
5
|
+
t.string :likeable_identify, null: false
|
6
|
+
t.references :likeable, :polymorphic => true, :null => false
|
7
|
+
|
8
|
+
#you maybe need change this column
|
9
|
+
t.references :user
|
10
|
+
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
#indexes
|
15
|
+
#add_index :likes, [:user_id, :likeable_id, :likeable_type], :unique => true
|
16
|
+
#add_index :likes, :user_id
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class MyFeedsMigration < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :feeds do |t|
|
4
|
+
#necessarily
|
5
|
+
t.references :source, :polymorphic => true, :null => false
|
6
|
+
t.string :source_identify, null: false
|
7
|
+
t.string :event, null: false
|
8
|
+
|
9
|
+
#not necessarily, but maybe you need
|
10
|
+
#you can also customize your columns
|
11
|
+
t.references :target, :polymorphic => true
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :feeds, :source_identify
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Feed < ActiveRecord::Base
|
2
|
+
include MyFeeds::Identify
|
3
|
+
attr_accessible :source_id, :source_type, :event, :target_id, :target_type
|
4
|
+
|
5
|
+
#verify event uniqueness
|
6
|
+
#validates :event, uniqueness: {scope: [:source_id, :source_type, :target_id, :target_type]}, :if => :target_id
|
7
|
+
|
8
|
+
belongs_to :source, polymorphic: true
|
9
|
+
belongs_to :target, polymorphic: true
|
10
|
+
end
|
data/my_feeds.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'my_feeds/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "my_feeds"
|
8
|
+
spec.version = MyFeeds::VERSION
|
9
|
+
spec.authors = ["jjy"]
|
10
|
+
spec.email = ["jjyruby@gmail.com"]
|
11
|
+
spec.description = %q{Help you implement feeds / timeline in rails application.}
|
12
|
+
spec.summary = %q{my_feeds provide feed model and some helper methods, allow you to customize.}
|
13
|
+
spec.homepage = "https://github.com/jjyr/my_feeds"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
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_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: my_feeds
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- jjy
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
none: false
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.3'
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
none: false
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
prerelease: false
|
28
|
+
type: :development
|
29
|
+
name: bundler
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
none: false
|
33
|
+
requirements:
|
34
|
+
- - ! '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
prerelease: false
|
44
|
+
type: :development
|
45
|
+
name: rake
|
46
|
+
description: Help you implement feeds / timeline in rails application.
|
47
|
+
email:
|
48
|
+
- jjyruby@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- LICENSE.txt
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- lib/my_feeds.rb
|
59
|
+
- lib/my_feeds/eater.rb
|
60
|
+
- lib/my_feeds/feeder.rb
|
61
|
+
- lib/my_feeds/identify.rb
|
62
|
+
- lib/my_feeds/version.rb
|
63
|
+
- lib/rails/generators/my_feeds/likes_generator.rb
|
64
|
+
- lib/rails/generators/my_feeds_generator.rb
|
65
|
+
- lib/rails/generators/templates/like_model.rb
|
66
|
+
- lib/rails/generators/templates/likes_migration.rb
|
67
|
+
- lib/rails/generators/templates/migration.rb
|
68
|
+
- lib/rails/generators/templates/model.rb
|
69
|
+
- my_feeds.gemspec
|
70
|
+
homepage: https://github.com/jjyr/my_feeds
|
71
|
+
licenses:
|
72
|
+
- MIT
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.8.25
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: my_feeds provide feed model and some helper methods, allow you to customize.
|
95
|
+
test_files: []
|