action-store 0.2.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG +10 -0
- data/LICENSE +21 -0
- data/README.md +178 -0
- data/Rakefile +32 -0
- data/app/models/action.rb +4 -0
- data/config/initializers/action_store.rb +3 -0
- data/db/migrate/20170204035500_create_actions.rb +17 -0
- data/lib/action-store.rb +21 -0
- data/lib/action_store/configuration.rb +4 -0
- data/lib/action_store/engine.rb +10 -0
- data/lib/action_store/mixin.rb +215 -0
- data/lib/action_store/model.rb +11 -0
- data/lib/action_store/version.rb +3 -0
- data/lib/generators/action_store/install_generator.rb +17 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8620df9bc8e7e653ee263d433f892c7cdca53033
|
4
|
+
data.tar.gz: 73945fc330e36f657d39e2522e64572edac4a5ad
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 875ca9ea784edc3fbb850bf236aa81ebde12a5609cf184673cae8527c36da1716e45ebe7d8399c951183f2fd3640fcea79b586127a2b12a15b266a1a5905226d
|
7
|
+
data.tar.gz: 0fd1ac9eadc6e0603d149d2b2bd781535b7dede284df05ec7eb7cbd5099a3f222c06cb29f9bedabe845f98cfa3e5933dea0ef7209f1de56c7512cfa4b2a57154
|
data/CHANGELOG
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2017 Rails Engine
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
ActionStore
|
2
|
+
-----------
|
3
|
+
|
4
|
+
[](https://badge.fury.io/rb/action-store) [](https://travis-ci.org/rails-engine/action-store) [](https://codeclimate.com/github/rails-engine/action-store) [](https://codecov.io/github/rails-engine/action-store?branch=master) [](http://inch-ci.org/github/rails-engine/action-store?branch=master)
|
5
|
+
|
6
|
+
Store difference kind of actions (Like, Follow, Star, Block ...) in one table via ActiveRecord Polymorphic Association.
|
7
|
+
|
8
|
+
- Like Post/Comment/Reply ...
|
9
|
+
- Watch/Subscribe Post
|
10
|
+
- Follow User
|
11
|
+
- Favorite Post
|
12
|
+
- Read Notification/Message
|
13
|
+
|
14
|
+
And more and more.
|
15
|
+
|
16
|
+
## Basic table struct
|
17
|
+
|
18
|
+
| Field | Means |
|
19
|
+
| ----- | ----- |
|
20
|
+
| `action_type` | The type of action [like, watch, follow, star, favorite] |
|
21
|
+
| `action_option` | Secondly option for store you custom status, or you can let it null if you don't needs it. |
|
22
|
+
| `target_type`, `target_id` | Polymorphic Association for difference `Target` models [User, Post, Comment] |
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
```rb
|
27
|
+
gem 'action-store'
|
28
|
+
```
|
29
|
+
|
30
|
+
and run `bundle install`
|
31
|
+
|
32
|
+
### Define Actions
|
33
|
+
|
34
|
+
You can use `action_store` to define actions:
|
35
|
+
|
36
|
+
app/models/user.rb
|
37
|
+
|
38
|
+
```
|
39
|
+
class User < ActiveRecord::Base
|
40
|
+
action_store <action_type>, <target>, opts
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
#### Convention Over Configuration:
|
45
|
+
|
46
|
+
| action, target | Target Model | Target `counter_cache_field` | User `counter_cache_field` | Target has_many | User has_many |
|
47
|
+
| ------ | ------ | ------ | ------ | ------ | ------ | ------ |
|
48
|
+
| `action_store :like, :post` | `Post` | | | `has_many :like_by_user_actions`, `has_many :like_by_users` | `has_many :like_post_actions`, `has_many :like_posts` |
|
49
|
+
| `action_store :like, :post, counter_cache: true` | `Post` | `likes_count` | | `has_many :like_by_user_actions`, `has_many :like_by_users` | `has_many :like_post_actions`, `has_many :like_posts` |
|
50
|
+
| `action_store :star, :project, class_name: 'Repository'` | `Repository ` | `stars_count` | `star_projects_count` | `has_many :star_by_user_actions`, `has_many :star_by_users` |
|
51
|
+
| `action_store :follow, :user` | `User` | `follows_count` | `follow_users_count` | `has_many :follow_by_user_actions`, `has_many :follow_by_users` | `has_many :follow_user_actions`, `has_many :follow_users` |
|
52
|
+
| `action_store :follow, :user, counter_cache: 'followers_count', user_counter_cache: 'following_count'` | `User` | `followers_count ` | `following_count ` | `has_many :follow_by_user_actions`, `has_many :follow_by_users` | `has_many :follow_user_actions`, `has_many :follow_users` |
|
53
|
+
|
54
|
+
for example:
|
55
|
+
|
56
|
+
```rb
|
57
|
+
# app/models/action.rb
|
58
|
+
class User < ActiveRecord::Base
|
59
|
+
action_store :like, :post, counter_cache: true
|
60
|
+
action_store :star, :post, counter_cache: true, user_counter_cache: true
|
61
|
+
action_store :follow, :post
|
62
|
+
action_store :like, :comment, counter_cache: true
|
63
|
+
action_store :follow, :user, counter_cache: 'followers_count', user_counter_cache: 'following_count'
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
### Counter Cache
|
68
|
+
|
69
|
+
And you need add counter_cache field to target, user table.
|
70
|
+
|
71
|
+
```rb
|
72
|
+
add_column :users, :star_posts_count, :integer, default: 0
|
73
|
+
add_column :users, :followers_count, :integer, default: 0
|
74
|
+
add_column :users, :following_count, :integer, default: 0
|
75
|
+
|
76
|
+
add_column :posts, :likes_count, :integer, default: 0
|
77
|
+
add_column :posts, :stars_count, :integer, default: 0
|
78
|
+
|
79
|
+
add_column :comments, :likes_count, :integer, default: 0
|
80
|
+
```
|
81
|
+
|
82
|
+
#### Now you can use like this:
|
83
|
+
|
84
|
+
@user -> like @post
|
85
|
+
|
86
|
+
```rb
|
87
|
+
irb> User.create_action(:like, target: @post, user: @user)
|
88
|
+
true
|
89
|
+
irb> @user.create_action(:like, target: @post)
|
90
|
+
true
|
91
|
+
irb> @post.reload.likes_count
|
92
|
+
1
|
93
|
+
```
|
94
|
+
|
95
|
+
@user1 -> unlike @user2
|
96
|
+
|
97
|
+
```rb
|
98
|
+
irb> User.destroy_action(:follow, target: @post, user: @user)
|
99
|
+
true
|
100
|
+
irb> @user.destroy_action(:like, target: @post)
|
101
|
+
true
|
102
|
+
irb> @post.reload.likes_count
|
103
|
+
0
|
104
|
+
```
|
105
|
+
|
106
|
+
Check @user1 is liked @post
|
107
|
+
|
108
|
+
```rb
|
109
|
+
irb> action = User.find_action(:follow, target: @post, user: @user)
|
110
|
+
irb> action = @user.find_action(:like, target: @post)
|
111
|
+
irb> action.present?
|
112
|
+
true
|
113
|
+
```
|
114
|
+
|
115
|
+
User follow cases:
|
116
|
+
|
117
|
+
```rb
|
118
|
+
# @user1 -> follow @user2
|
119
|
+
@user1.create_action(:follow, target: @user2)
|
120
|
+
@user1.reload.following_count => 1
|
121
|
+
@user2.reload.followers_count_ => 1
|
122
|
+
@user1.follow_user?(@user2) => true
|
123
|
+
# @user2 -> follow @user1
|
124
|
+
@user2.create_action(:follow, target: @user1)
|
125
|
+
@user2.follow_user?(@user1) => true
|
126
|
+
# @user1 -> follow @user3
|
127
|
+
@user1.create_action(:follow, target: @user3)
|
128
|
+
# @user1 -> unfollow @user3
|
129
|
+
@user1.destroy_action(:follow, target: @user3)
|
130
|
+
```
|
131
|
+
|
132
|
+
## Builtin relations and methods
|
133
|
+
|
134
|
+
When you called `action_store`, ActionStore will define Many-to-Many relations for User and Target model.
|
135
|
+
|
136
|
+
for example:
|
137
|
+
|
138
|
+
```rb
|
139
|
+
class User < ActiveRecord::Base
|
140
|
+
action_store :like, :post
|
141
|
+
action_store :block, :user
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
It will defines Many-to-Many relations:
|
146
|
+
|
147
|
+
- For User model will defined: `<action>_<target>s` (like_posts)
|
148
|
+
- For Target model will defined: `<action>_by_users` (like_by_users)
|
149
|
+
|
150
|
+
```rb
|
151
|
+
# for User model
|
152
|
+
has_many :like_post_actions
|
153
|
+
has_many :like_posts, through: :like_post_actions
|
154
|
+
## as user
|
155
|
+
has_many :block_user_actions
|
156
|
+
has_many :block_users, through: :block_user_actions
|
157
|
+
## as target
|
158
|
+
has_many :block_by_user_actions
|
159
|
+
has_many :block_by_users, through: :block_by_user_actions
|
160
|
+
|
161
|
+
# for Target model
|
162
|
+
has_many :like_by_user_actions
|
163
|
+
has_many :like_by_users, through: :like_user_actions
|
164
|
+
```
|
165
|
+
|
166
|
+
And `User` model will have methods:
|
167
|
+
|
168
|
+
- @user.create_action(:like, target: @post)
|
169
|
+
- @user.destroy_action(:like, target: @post)
|
170
|
+
- @user.find_action(:like, target: @post)
|
171
|
+
- @user.like_post(@post)
|
172
|
+
- @user.like_post?(@post)
|
173
|
+
- @user.unlike_post(@post)
|
174
|
+
- @user.block_user(@user1)
|
175
|
+
- @user.unblock_user(@user1)
|
176
|
+
- @user.like_post_ids
|
177
|
+
- @user.block_user_ids
|
178
|
+
- @user.block_by_user_ids
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Actionstore'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
load 'rails/tasks/statistics.rake'
|
20
|
+
|
21
|
+
require 'bundler/gem_tasks'
|
22
|
+
require 'rake/testtask'
|
23
|
+
|
24
|
+
Rake::TestTask.new(:test) do |t|
|
25
|
+
t.libs << 'lib'
|
26
|
+
t.libs << 'test'
|
27
|
+
t.pattern = 'test/**/*_test.rb'
|
28
|
+
t.verbose = false
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
task default: :test
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateActions < ActiveRecord::Migration[5.0]
|
2
|
+
def change
|
3
|
+
create_table :actions do |t|
|
4
|
+
t.string :action_type, null: false
|
5
|
+
t.string :action_option
|
6
|
+
t.string :target_type
|
7
|
+
t.integer :target_id
|
8
|
+
t.string :user_type
|
9
|
+
t.integer :user_id
|
10
|
+
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index :actions, [:user_type, :user_id, :action_type]
|
15
|
+
add_index :actions, [:target_type, :target_id, :action_type]
|
16
|
+
end
|
17
|
+
end
|
data/lib/action-store.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "action_store/version"
|
2
|
+
require "action_store/configuration"
|
3
|
+
require "action_store/engine"
|
4
|
+
require "action_store/model"
|
5
|
+
require "action_store/mixin"
|
6
|
+
|
7
|
+
module ActionStore
|
8
|
+
class << self
|
9
|
+
def config
|
10
|
+
return @config if defined?(@config)
|
11
|
+
@config = Configuration.new
|
12
|
+
@config
|
13
|
+
end
|
14
|
+
|
15
|
+
def configure(&block)
|
16
|
+
config.instance_exec(&block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
ActiveRecord::Base.send(:include, ActionStore::Mixin)
|
@@ -0,0 +1,215 @@
|
|
1
|
+
module ActionStore
|
2
|
+
module Mixin
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
end
|
7
|
+
|
8
|
+
def find_action(action_type, opts)
|
9
|
+
opts[:user] = self
|
10
|
+
self.class.find_action(action_type, opts)
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_action(action_type, opts)
|
14
|
+
opts[:user] = self
|
15
|
+
self.class.create_action(action_type, opts)
|
16
|
+
end
|
17
|
+
|
18
|
+
def destroy_action(action_type, opts)
|
19
|
+
opts[:user] = self
|
20
|
+
self.class.destroy_action(action_type, opts)
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
attr_reader :defined_actions
|
25
|
+
|
26
|
+
def find_defined_action(action_type, name)
|
27
|
+
action_type = action_type.to_s
|
28
|
+
name = name.to_s.singularize.underscore
|
29
|
+
defined_actions.find { |a| a[:action_type] == action_type && a[:action_name] == name }
|
30
|
+
end
|
31
|
+
|
32
|
+
def action_store(action_type, name, opts = {})
|
33
|
+
opts ||= {}
|
34
|
+
klass_name = opts[:class_name] || name
|
35
|
+
target_klass = klass_name.to_s.classify.constantize
|
36
|
+
action_type = action_type.to_s
|
37
|
+
if opts[:counter_cache] == true
|
38
|
+
# @post.stars_count
|
39
|
+
opts[:counter_cache] = "#{action_type.pluralize}_count"
|
40
|
+
end
|
41
|
+
if opts[:user_counter_cache] == true
|
42
|
+
# @user.star_posts_count
|
43
|
+
opts[:user_counter_cache] = "#{action_type}_#{name.to_s.pluralize}_count"
|
44
|
+
end
|
45
|
+
|
46
|
+
@defined_actions ||= []
|
47
|
+
action = {
|
48
|
+
action_name: name.to_s,
|
49
|
+
action_type: action_type,
|
50
|
+
target_klass: target_klass,
|
51
|
+
counter_cache: opts[:counter_cache],
|
52
|
+
user_counter_cache: opts[:user_counter_cache]
|
53
|
+
}
|
54
|
+
@defined_actions << action
|
55
|
+
|
56
|
+
define_relations(action)
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_action(action_type, opts)
|
60
|
+
opts[:action_type] = action_type
|
61
|
+
opts = safe_action_opts(opts)
|
62
|
+
return nil if opts[:user_id].blank? || opts[:user_type].blank?
|
63
|
+
return nil if opts[:target_id].blank? || opts[:target_type].blank?
|
64
|
+
|
65
|
+
defined_action = find_defined_action(opts[:action_type], opts[:target_type])
|
66
|
+
return nil if defined_action.nil?
|
67
|
+
|
68
|
+
Action.find_by(where_opts(opts))
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_action(action_type, opts)
|
72
|
+
opts[:action_type] = action_type
|
73
|
+
opts = safe_action_opts(opts)
|
74
|
+
return false if opts[:user_id].blank? || opts[:user_type].blank?
|
75
|
+
return false if opts[:target_id].blank? || opts[:target_type].blank?
|
76
|
+
|
77
|
+
defined_action = find_defined_action(opts[:action_type], opts[:target_type])
|
78
|
+
return false if defined_action.nil?
|
79
|
+
|
80
|
+
action = Action.find_or_create_by(where_opts(opts))
|
81
|
+
if opts[:action_option]
|
82
|
+
action.update_attribute(:action_option, opts[:action_option])
|
83
|
+
end
|
84
|
+
reset_counter_cache(action, defined_action)
|
85
|
+
true
|
86
|
+
end
|
87
|
+
|
88
|
+
def destroy_action(action_type, opts)
|
89
|
+
opts[:action_type] = action_type
|
90
|
+
opts = safe_action_opts(opts)
|
91
|
+
return false if opts[:user_id].blank? || opts[:user_type].blank?
|
92
|
+
return false if opts[:target_id].blank? || opts[:target_type].blank?
|
93
|
+
|
94
|
+
defined_action = find_defined_action(opts[:action_type], opts[:target_type])
|
95
|
+
return false if defined_action.nil?
|
96
|
+
|
97
|
+
action = Action.where(where_opts(opts)).first
|
98
|
+
return true if !action
|
99
|
+
action.destroy
|
100
|
+
reset_counter_cache(action, defined_action)
|
101
|
+
true
|
102
|
+
end
|
103
|
+
|
104
|
+
def reset_counter_cache(action, defined_action)
|
105
|
+
return false if action.blank?
|
106
|
+
if defined_action[:counter_cache] && action.target.present?
|
107
|
+
target_count = Action.where({ action_type: defined_action[:action_type], target: action.target }).count
|
108
|
+
action.target.update_attribute(defined_action[:counter_cache], target_count)
|
109
|
+
end
|
110
|
+
if defined_action[:user_counter_cache] && action.user.present?
|
111
|
+
user_count = Action.where({ action_type: defined_action[:action_type], user: action.user }).count
|
112
|
+
action.user.update_attribute(defined_action[:user_counter_cache], user_count)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def define_relations(action)
|
119
|
+
target_klass = action[:target_klass]
|
120
|
+
action_type = action[:action_type]
|
121
|
+
action_name = action[:action_name]
|
122
|
+
|
123
|
+
user_klass = self
|
124
|
+
|
125
|
+
# user, person
|
126
|
+
user_name = user_klass.name.underscore.singularize
|
127
|
+
|
128
|
+
# like_topic, follow_user
|
129
|
+
full_action_name = [action_type, action_name].join('_')
|
130
|
+
# like_user, follow_user
|
131
|
+
full_action_name_for_target = [action_type, 'by', user_name].join('_')
|
132
|
+
# unlike_topic, unfollow_user
|
133
|
+
unaction_name = "un#{full_action_name}"
|
134
|
+
|
135
|
+
# @target.like_topic_actions, @target.follow_user_actions
|
136
|
+
has_many_name = [full_action_name, 'actions'].join('_').to_sym
|
137
|
+
# @target.like_topics, @target.follow_users
|
138
|
+
has_many_through_name = full_action_name.pluralize.to_sym
|
139
|
+
|
140
|
+
# @user.like_by_user_actions, @user.follow_by_user_actions
|
141
|
+
has_many_name_for_target = [full_action_name_for_target, 'actions'].join('_').to_sym
|
142
|
+
# @user.like_by_users, @user.follow_by_users
|
143
|
+
has_many_through_name_for_target = full_action_name_for_target.pluralize.to_sym
|
144
|
+
|
145
|
+
has_many_scope = -> {
|
146
|
+
where(action_type: action_type, target_type: target_klass.name, user_type: user_klass.name)
|
147
|
+
}
|
148
|
+
|
149
|
+
# User has_many :like_topic_actions
|
150
|
+
user_klass.send :has_many, has_many_name, has_many_scope, class_name: 'Action'
|
151
|
+
# User has_many :like_topics
|
152
|
+
user_klass.send :has_many, has_many_through_name,
|
153
|
+
through: has_many_name,
|
154
|
+
source: :target,
|
155
|
+
source_type: target_klass.name
|
156
|
+
|
157
|
+
# Topic has_many :like_user_actions
|
158
|
+
target_klass.send :has_many, has_many_name_for_target, has_many_scope,
|
159
|
+
foreign_key: :target_id,
|
160
|
+
class_name: 'Action'
|
161
|
+
# Topic has_many :like_users
|
162
|
+
target_klass.send :has_many, has_many_through_name_for_target,
|
163
|
+
through: has_many_name_for_target,
|
164
|
+
source_type: user_klass.name,
|
165
|
+
source: :user
|
166
|
+
|
167
|
+
# @user.like_topic
|
168
|
+
user_klass.send(:define_method, full_action_name) do |target_or_id|
|
169
|
+
target_id = target_or_id.is_a?(target_klass) ? target_or_id.id : target_or_id
|
170
|
+
result = user_klass.create_action(action_type, target_type: target_klass.name,
|
171
|
+
target_id: target_id,
|
172
|
+
user: self)
|
173
|
+
self.reload
|
174
|
+
result
|
175
|
+
end
|
176
|
+
|
177
|
+
# @user.like_topic?
|
178
|
+
user_klass.send(:define_method, "#{full_action_name}?") do |target_or_id|
|
179
|
+
target_id = target_or_id.is_a?(target_klass) ? target_or_id.id : target_or_id
|
180
|
+
result = user_klass.find_action(action_type, target_type: target_klass.name,
|
181
|
+
target_id: target_id,
|
182
|
+
user: self)
|
183
|
+
result.present?
|
184
|
+
end
|
185
|
+
|
186
|
+
# @user.unlike_topic
|
187
|
+
user_klass.send(:define_method, unaction_name) do |target_or_id|
|
188
|
+
target_id = target_or_id.is_a?(target_klass) ? target_or_id.id : target_or_id
|
189
|
+
result = user_klass.destroy_action(action_type, target_type: target_klass.name,
|
190
|
+
target_id: target_id,
|
191
|
+
user: self)
|
192
|
+
self.reload
|
193
|
+
result
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def safe_action_opts(opts)
|
198
|
+
opts ||= {}
|
199
|
+
if opts[:user]
|
200
|
+
opts[:user_id] = opts[:user].id
|
201
|
+
opts[:user_type] = opts[:user].class.name
|
202
|
+
end
|
203
|
+
if opts[:target]
|
204
|
+
opts[:target_type] = opts[:target].class.name
|
205
|
+
opts[:target_id] = opts[:target].id
|
206
|
+
end
|
207
|
+
opts
|
208
|
+
end
|
209
|
+
|
210
|
+
def where_opts(opts)
|
211
|
+
opts.extract!(:action_type, :target_type, :target_id, :user_id, :user_type)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
module ActionStore
|
3
|
+
module Generators
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
desc "Create ActionStore's base files"
|
6
|
+
source_root File.expand_path('../../../../', __FILE__)
|
7
|
+
|
8
|
+
def add_initializer
|
9
|
+
template 'config/initializers/action_store.rb', 'config/initializers/action_store.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_migrations
|
13
|
+
exec('rake action_store:install:migrations')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: action-store
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jason Lee
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-02-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.2.0
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5.1'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 4.2.0
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5.1'
|
33
|
+
description: Store difference kind of actions (Like, Follow, Star, Block ...) in one
|
34
|
+
table via ActiveRecord Polymorphic Association.
|
35
|
+
email: huacnlee@gmail.com
|
36
|
+
executables: []
|
37
|
+
extensions: []
|
38
|
+
extra_rdoc_files: []
|
39
|
+
files:
|
40
|
+
- CHANGELOG
|
41
|
+
- LICENSE
|
42
|
+
- README.md
|
43
|
+
- Rakefile
|
44
|
+
- app/models/action.rb
|
45
|
+
- config/initializers/action_store.rb
|
46
|
+
- db/migrate/20170204035500_create_actions.rb
|
47
|
+
- lib/action-store.rb
|
48
|
+
- lib/action_store/configuration.rb
|
49
|
+
- lib/action_store/engine.rb
|
50
|
+
- lib/action_store/mixin.rb
|
51
|
+
- lib/action_store/model.rb
|
52
|
+
- lib/action_store/version.rb
|
53
|
+
- lib/generators/action_store/install_generator.rb
|
54
|
+
homepage: https://github.com/rails-engine/action-store
|
55
|
+
licenses:
|
56
|
+
- MIT
|
57
|
+
metadata: {}
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 2.5.2
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: Store difference kind of actions (Like, Follow, Star, Block ...) in one table.
|
78
|
+
test_files: []
|