action-store 0.4.4 → 1.1.2
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 +4 -4
- data/CHANGELOG.md +51 -21
- data/README.md +73 -19
- data/Rakefile +2 -2
- data/app/models/action.rb +1 -0
- data/config/initializers/action_store.rb +1 -0
- data/db/migrate/20170204035500_create_actions.rb +10 -9
- data/db/migrate/20181121052638_add_unique_index_to_actions.rb +5 -2
- data/lib/action-store.rb +2 -0
- data/lib/action_store/configuration.rb +1 -0
- data/lib/action_store/engine.rb +1 -0
- data/lib/action_store/mixin.rb +115 -111
- data/lib/action_store/model.rb +1 -0
- data/lib/action_store/version.rb +2 -1
- data/lib/generators/action_store/install_generator.rb +2 -1
- metadata +10 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 394f0ac4dd31e9c98ae5052769ef935f67f8de6ab25401b34a529fd79fb5c7fd
|
4
|
+
data.tar.gz: 2682434ea7b22e756d5e78e4f97afb1986b75fe15f128668f9ce863c9c862616
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06d674a641954289d95e8aa192608fa05ca9040a9a7eea1256c13b0b9499891a2486277b39371c73288fcc2f50922033a80016a22eeb2f7282978ff786f2ee2b
|
7
|
+
data.tar.gz: c550135c83fa5ec9c71ae993f87c3b5f9344a6dcbe175448365eecbbaee1f38e490b808096a506ea7209b61a1ad1e4e297a94dd052db5234e7bcda1d58c2a583
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,34 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
## 1.1.1
|
2
|
+
|
3
|
+
- Update Table column limit for fix MySQL max key length error. (#17)
|
4
|
+
|
5
|
+
## 1.1.0
|
6
|
+
|
7
|
+
- Allows to configure different Models / Tables for store actions. (#16)
|
8
|
+
|
9
|
+
```rb
|
10
|
+
# app/models/like.rb
|
11
|
+
class Like < Action
|
12
|
+
self.table_name = "likes"
|
13
|
+
end
|
14
|
+
```
|
15
|
+
|
16
|
+
```rb
|
17
|
+
# app/models/user.rb
|
18
|
+
class User < ActiveRecord::Base
|
19
|
+
action_store :like, :post, counter_cache: true, action_class_name: "Like"
|
20
|
+
action_store :like, :comment, counter_cache: true, action_class_name: "Like"
|
21
|
+
end
|
22
|
+
```
|
23
|
+
|
24
|
+
## 1.0.0
|
25
|
+
|
26
|
+
- Require Rails >= 5.2.
|
27
|
+
- Fix primary key for use `bigint` column type.
|
28
|
+
|
29
|
+
0.4.3
|
30
|
+
|
31
|
+
---
|
3
32
|
|
4
33
|
- Auto reload `target`, when action/unaction target.
|
5
34
|
|
@@ -14,8 +43,7 @@ irb> post.likes_count
|
|
14
43
|
=> 0
|
15
44
|
```
|
16
45
|
|
17
|
-
0.4.2
|
18
|
-
-----
|
46
|
+
## 0.4.2
|
19
47
|
|
20
48
|
- Add `UNIQUE INDEX` on `:action_type, :target_type, :target_id, :user_type, :user_id` for makesure action uniqueness.
|
21
49
|
> NOTE! If you already have actions in database, the new migration may have issue on `db:migrate`,
|
@@ -32,25 +60,27 @@ $ rails g action_store:install
|
|
32
60
|
Overwrite config/initializers/action_store.rb? (enter "h" for help) [Ynaqdhm] n
|
33
61
|
skip config/initializers/action_store.rb
|
34
62
|
Copied migration 20181121061544_add_unique_index_to_actions.action_store.rb from action_store
|
35
|
-
|
63
|
+
```
|
36
64
|
|
37
|
-
0.3.3
|
38
|
-
-----
|
65
|
+
## 0.3.3
|
39
66
|
|
40
67
|
- Fix for supports Rails 5.2;
|
41
68
|
|
42
|
-
0.3.2
|
43
|
-
|
69
|
+
0.3.2
|
70
|
+
|
71
|
+
---
|
44
72
|
|
45
73
|
- Gem dependency for Rails 5.x.
|
46
74
|
|
47
|
-
0.3.1
|
48
|
-
|
75
|
+
0.3.1
|
76
|
+
|
77
|
+
---
|
49
78
|
|
50
79
|
- Fix that `:user_counter_cache` was incorrect, it not count with target_type.
|
51
80
|
|
52
|
-
0.3.0
|
53
|
-
|
81
|
+
0.3.0
|
82
|
+
|
83
|
+
---
|
54
84
|
|
55
85
|
- Fix for action_store in Model that not named `User`.
|
56
86
|
- Fix has_many name when `User` model in a namespace.
|
@@ -72,8 +102,7 @@ end
|
|
72
102
|
@blog_user.like_post(@post), @post.like_by_blog_users, @post.like_by_blog_user_actions
|
73
103
|
```
|
74
104
|
|
75
|
-
0.2.2
|
76
|
-
-----
|
105
|
+
## 0.2.2
|
77
106
|
|
78
107
|
- Fix #2 support Target that under a namespace.
|
79
108
|
|
@@ -81,18 +110,19 @@ end
|
|
81
110
|
action_store :like, :blog_post, class_name: 'Blog::Post'
|
82
111
|
```
|
83
112
|
|
84
|
-
0.2.1
|
85
|
-
-----
|
113
|
+
## 0.2.1
|
86
114
|
|
87
115
|
- Use `ActiveSupport.on_load` to hook into Active Record.
|
88
116
|
|
89
|
-
0.2.0
|
90
|
-
|
117
|
+
0.2.0
|
118
|
+
|
119
|
+
---
|
91
120
|
|
92
121
|
- New API, define action in User model.
|
93
122
|
- Builtin Many-to-Many relations and methods.
|
94
123
|
|
95
|
-
0.1.0
|
96
|
-
|
124
|
+
0.1.0
|
125
|
+
|
126
|
+
---
|
97
127
|
|
98
128
|
- First release.
|
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
ActionStore
|
2
|
-
-----------
|
1
|
+
## ActionStore
|
3
2
|
|
4
|
-
[](https://badge.fury.io/rb/action-store) [](https://badge.fury.io/rb/action-store) [](https://github.com/rails-engine/action-store/actions?query=workflow%3Abuild) [](https://codecov.io/github/rails-engine/action-store?branch=master)
|
5
4
|
|
6
5
|
Store different kinds of actions (Like, Follow, Star, Block, etc.) in a single table via ActiveRecord Polymorphic Associations.
|
7
6
|
|
@@ -17,11 +16,12 @@ And more and more.
|
|
17
16
|
|
18
17
|
## Basic table struct
|
19
18
|
|
20
|
-
| Column | Description
|
21
|
-
|
|
22
|
-
| `action_type` | The type of action [like, watch, follow, star, favorite]
|
23
|
-
| `action_option` | Secondary option for storing your custom status, or null if unneeded.
|
24
|
-
| `target_type`, `target_id` | Polymorphic Association for different `Target` models [User, Post, Comment] |
|
19
|
+
| Column | Chars Limit | Description |
|
20
|
+
| -------------------------- | ----------- | --------------------------------------------------------------------------- |
|
21
|
+
| `action_type` | 64 | The type of action [like, watch, follow, star, favorite] |
|
22
|
+
| `action_option` | 64 | Secondary option for storing your custom status, or null if unneeded. |
|
23
|
+
| `target_type`, `target_id` | 64 | Polymorphic Association for different `Target` models [User, Post, Comment] |
|
24
|
+
| `user_type` | 64 | Polymorphic Association for different user model [User, Group, Member] |
|
25
25
|
|
26
26
|
### Uniqueness
|
27
27
|
|
@@ -51,9 +51,8 @@ and run `rails db:migrate`.
|
|
51
51
|
|
52
52
|
Use `action_store` to define actions:
|
53
53
|
|
54
|
-
app/models/user.rb
|
55
|
-
|
56
54
|
```rb
|
55
|
+
# app/models/user.rb
|
57
56
|
class User < ActiveRecord::Base
|
58
57
|
action_store <action_type>, <target>, opts
|
59
58
|
end
|
@@ -61,18 +60,18 @@ end
|
|
61
60
|
|
62
61
|
#### Convention Over Configuration:
|
63
62
|
|
64
|
-
| action, target
|
65
|
-
|
66
|
-
| `action_store :like, :post`
|
67
|
-
| `action_store :like, :post, counter_cache: true`
|
68
|
-
| `action_store :star, :project, class_name: 'Repository'`
|
69
|
-
| `action_store :follow, :user`
|
70
|
-
| `action_store :follow, :user, counter_cache: 'followers_count', user_counter_cache: 'following_count'` | `User`
|
63
|
+
| action, target | Target Model | Target `counter_cache_field` | User `counter_cache_field` | Target has_many | User has_many |
|
64
|
+
| ------------------------------------------------------------------------------------------------------ | ------------- | ---------------------------- | -------------------------- | --------------------------------------------------------------- | --------------------------------------------------------- |
|
65
|
+
| `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` |
|
66
|
+
| `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` |
|
67
|
+
| `action_store :star, :project, class_name: 'Repository'` | `Repository ` | `stars_count` | `star_projects_count` | `has_many :star_by_user_actions`, `has_many :star_by_users` |
|
68
|
+
| `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` |
|
69
|
+
| `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` |
|
71
70
|
|
72
71
|
for example:
|
73
72
|
|
74
73
|
```rb
|
75
|
-
# app/models/
|
74
|
+
# app/models/user.rb
|
76
75
|
class User < ActiveRecord::Base
|
77
76
|
action_store :like, :post, counter_cache: true
|
78
77
|
action_store :star, :post, counter_cache: true, user_counter_cache: true
|
@@ -137,7 +136,7 @@ true
|
|
137
136
|
irb> @user1.create_action(:follow, target: @user2)
|
138
137
|
irb> @user1.reload.following_count
|
139
138
|
=> 1
|
140
|
-
irb> @user2.reload.
|
139
|
+
irb> @user2.reload.followers_count
|
141
140
|
=> 1
|
142
141
|
irb> @user1.follow_user?(@user2)
|
143
142
|
=> true
|
@@ -181,6 +180,61 @@ irb> @issue.subscribe_by_user_actions.where(action_option: nil).count
|
|
181
180
|
=> 0
|
182
181
|
```
|
183
182
|
|
183
|
+
## Use different tables for store actions.
|
184
|
+
|
185
|
+
> since 1.1.0
|
186
|
+
|
187
|
+
Sometimes, you may want to store actions into different table, for example, **Like** scenarios often have a lot of data, we wants store them into `likes` table.
|
188
|
+
|
189
|
+
Create a migration and model
|
190
|
+
|
191
|
+
```bash
|
192
|
+
$ rails g migration create_likes
|
193
|
+
```
|
194
|
+
|
195
|
+
And then modify this migration file to let this table have same struct like the `actions`
|
196
|
+
|
197
|
+
```rb
|
198
|
+
class CreateLikes < ActiveRecord::Migration[6.1]
|
199
|
+
def change
|
200
|
+
create_table :likes do |t|
|
201
|
+
t.string :action_type, null: false
|
202
|
+
t.string :action_option
|
203
|
+
t.string :target_type
|
204
|
+
t.bigint :target_id
|
205
|
+
t.string :user_type
|
206
|
+
t.bigint :user_id
|
207
|
+
|
208
|
+
t.timestamps
|
209
|
+
end
|
210
|
+
|
211
|
+
add_index :likes, %i[user_type user_id action_type]
|
212
|
+
add_index :likes, %i[target_type target_id action_type]
|
213
|
+
add_index :likes, %i[action_type target_type target_id user_type user_id], unique: true, name: :uk_likes_target_user
|
214
|
+
end
|
215
|
+
end
|
216
|
+
```
|
217
|
+
|
218
|
+
Create a `app/model/like.rb` model file:
|
219
|
+
|
220
|
+
```rb
|
221
|
+
class Like < Action
|
222
|
+
self.table_name = "likes"
|
223
|
+
end
|
224
|
+
```
|
225
|
+
|
226
|
+
And then change you `action_store` define to special some case to use Like model:
|
227
|
+
|
228
|
+
```rb
|
229
|
+
# app/models/user.rb
|
230
|
+
class User < ActiveRecord::Base
|
231
|
+
action_store :like, :post, counter_cache: true, action_class_name: "Like"
|
232
|
+
action_store :like, :comment, counter_cache: true, action_class_name: "Like"
|
233
|
+
end
|
234
|
+
```
|
235
|
+
|
236
|
+
Now, `user.like_post`, `user.like_comment` will store the actions into `likes` table.
|
237
|
+
|
184
238
|
## Built-in relations and methods
|
185
239
|
|
186
240
|
When you call `action_store`, ActionStore will define many-to-many relations for User and Target models.
|
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
begin
|
3
4
|
require "bundler/setup"
|
4
5
|
rescue LoadError
|
@@ -15,7 +16,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
15
16
|
rdoc.rdoc_files.include("lib/**/*.rb")
|
16
17
|
end
|
17
18
|
|
18
|
-
APP_RAKEFILE = File.expand_path("
|
19
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
19
20
|
load "rails/tasks/engine.rake"
|
20
21
|
load "rails/tasks/statistics.rake"
|
21
22
|
|
@@ -29,5 +30,4 @@ Rake::TestTask.new(:test) do |t|
|
|
29
30
|
t.verbose = false
|
30
31
|
end
|
31
32
|
|
32
|
-
|
33
33
|
task default: :test
|
data/app/models/action.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
class CreateActions < ActiveRecord::Migration[5.2]
|
3
4
|
def change
|
4
5
|
create_table :actions do |t|
|
5
|
-
t.string :action_type, null: false
|
6
|
-
t.string :action_option
|
7
|
-
t.string :target_type
|
8
|
-
t.
|
9
|
-
t.string :user_type
|
10
|
-
t.
|
6
|
+
t.string :action_type, null: false, limit: 64
|
7
|
+
t.string :action_option, limit: 64
|
8
|
+
t.string :target_type, limit: 64
|
9
|
+
t.bigint :target_id
|
10
|
+
t.string :user_type, limit: 64
|
11
|
+
t.bigint :user_id
|
11
12
|
|
12
13
|
t.timestamps
|
13
14
|
end
|
14
15
|
|
15
|
-
add_index :actions, [
|
16
|
-
add_index :actions, [
|
16
|
+
add_index :actions, %i[user_type user_id action_type]
|
17
|
+
add_index :actions, %i[target_type target_id action_type]
|
17
18
|
end
|
18
19
|
end
|
@@ -1,5 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddUniqueIndexToActions < ActiveRecord::Migration[5.2]
|
2
4
|
def change
|
3
|
-
add_index :actions, [
|
5
|
+
add_index :actions, %i[action_type target_type target_id user_type user_id], unique: true,
|
6
|
+
name: :uk_action_target_user
|
4
7
|
end
|
5
8
|
end
|
data/lib/action-store.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "action_store/version"
|
3
4
|
require "action_store/configuration"
|
4
5
|
require "action_store/engine"
|
@@ -9,6 +10,7 @@ module ActionStore
|
|
9
10
|
class << self
|
10
11
|
def config
|
11
12
|
return @config if defined?(@config)
|
13
|
+
|
12
14
|
@config = Configuration.new
|
13
15
|
@config
|
14
16
|
end
|
data/lib/action_store/engine.rb
CHANGED
data/lib/action_store/mixin.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module ActionStore
|
3
4
|
module Mixin
|
4
5
|
extend ActiveSupport::Concern
|
@@ -32,32 +33,36 @@ module ActionStore
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
35
|
-
def action_store(action_type, name,
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
def action_store(action_type, name, class_name: nil, action_class_name: "Action", counter_cache: nil, user_counter_cache: nil)
|
37
|
+
name = name.to_s
|
38
|
+
|
39
|
+
class_name ||= name.classify
|
40
|
+
target_klass = class_name.constantize
|
41
|
+
action_klass = action_class_name.constantize
|
39
42
|
action_type = action_type.to_s
|
40
|
-
if
|
43
|
+
if counter_cache == true
|
41
44
|
# @post.stars_count
|
42
|
-
|
45
|
+
counter_cache = "#{action_type.pluralize}_count"
|
43
46
|
end
|
44
|
-
if
|
47
|
+
if user_counter_cache == true
|
45
48
|
# @user.star_posts_count
|
46
|
-
|
49
|
+
user_counter_cache = "#{action_type}_#{name.pluralize}_count"
|
47
50
|
end
|
48
51
|
|
49
52
|
@defined_actions ||= []
|
50
53
|
action = {
|
51
|
-
action_name: name
|
54
|
+
action_name: name,
|
52
55
|
action_type: action_type,
|
56
|
+
action_klass: action_klass,
|
53
57
|
target_klass: target_klass,
|
54
58
|
target_type: target_klass.name,
|
55
|
-
counter_cache:
|
56
|
-
user_counter_cache:
|
59
|
+
counter_cache: counter_cache,
|
60
|
+
user_counter_cache: user_counter_cache
|
57
61
|
}
|
58
62
|
@defined_actions << action
|
59
63
|
|
60
|
-
define_relations(
|
64
|
+
define_relations(action_klass: action_klass, target_klass: target_klass,
|
65
|
+
action_type: action_type, action_name: name)
|
61
66
|
end
|
62
67
|
|
63
68
|
def find_action(action_type, opts)
|
@@ -69,7 +74,7 @@ module ActionStore
|
|
69
74
|
defined_action = find_defined_action(opts[:action_type], opts[:target_type])
|
70
75
|
return nil if defined_action.nil?
|
71
76
|
|
72
|
-
|
77
|
+
defined_action[:action_klass].find_by(where_opts(opts))
|
73
78
|
end
|
74
79
|
|
75
80
|
def create_action(action_type, opts)
|
@@ -83,11 +88,11 @@ module ActionStore
|
|
83
88
|
|
84
89
|
# create! for raise RecordNotUnique
|
85
90
|
begin
|
86
|
-
action =
|
91
|
+
action = defined_action[:action_klass].find_or_create_by!(where_opts(opts))
|
87
92
|
action.update(action_option: opts[:action_option]) if opts.key?(:action_option)
|
88
93
|
rescue ActiveRecord::RecordNotUnique
|
89
94
|
# update action_option on exist
|
90
|
-
action =
|
95
|
+
action = defined_action[:action_klass].where(where_opts(opts)).take
|
91
96
|
action.update(action_option: opts[:action_option]) if opts.key?(:action_option)
|
92
97
|
end
|
93
98
|
|
@@ -104,8 +109,9 @@ module ActionStore
|
|
104
109
|
defined_action = find_defined_action(opts[:action_type], opts[:target_type])
|
105
110
|
return false if defined_action.nil?
|
106
111
|
|
107
|
-
action =
|
108
|
-
return true
|
112
|
+
action = defined_action[:action_klass].where(where_opts(opts)).first
|
113
|
+
return true unless action
|
114
|
+
|
109
115
|
action.destroy
|
110
116
|
reset_counter_cache(action, defined_action)
|
111
117
|
true
|
@@ -113,16 +119,18 @@ module ActionStore
|
|
113
119
|
|
114
120
|
def reset_counter_cache(action, defined_action)
|
115
121
|
return false if action.blank?
|
122
|
+
|
116
123
|
if defined_action[:counter_cache] && action.target.present?
|
117
|
-
target_count =
|
124
|
+
target_count = defined_action[:action_klass].where(
|
118
125
|
action_type: defined_action[:action_type],
|
119
126
|
target_type: action.target_type,
|
120
127
|
target_id: action.target_id
|
121
128
|
).count
|
122
129
|
action.target.update_attribute(defined_action[:counter_cache], target_count)
|
123
130
|
end
|
131
|
+
|
124
132
|
if defined_action[:user_counter_cache] && action.user.present?
|
125
|
-
user_count =
|
133
|
+
user_count = defined_action[:action_klass].where(
|
126
134
|
action_type: defined_action[:action_type],
|
127
135
|
target_type: action.target_type,
|
128
136
|
user_type: action.user_type,
|
@@ -134,105 +142,101 @@ module ActionStore
|
|
134
142
|
|
135
143
|
private
|
136
144
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
# @user.like_topic
|
189
|
-
user_klass.send(:define_method, full_action_name) do |target_or_id|
|
190
|
-
target_id = target_or_id.is_a?(target_klass) ? target_or_id.id : target_or_id
|
191
|
-
result = user_klass.create_action(action_type, target_type: target_klass.name,
|
192
|
-
target_id: target_id,
|
193
|
-
user: self)
|
194
|
-
target_or_id.reload if target_or_id.is_a?(target_klass)
|
195
|
-
self.reload
|
196
|
-
result
|
197
|
-
end
|
198
|
-
|
199
|
-
# @user.like_topic?
|
200
|
-
user_klass.send(:define_method, "#{full_action_name}?") do |target_or_id|
|
201
|
-
target_id = target_or_id.is_a?(target_klass) ? target_or_id.id : target_or_id
|
202
|
-
result = user_klass.find_action(action_type, target_type: target_klass.name,
|
145
|
+
def define_relations(target_klass:, action_klass:, action_type:, action_name:)
|
146
|
+
user_klass = self
|
147
|
+
|
148
|
+
# user, person
|
149
|
+
user_name = user_klass.table_name.underscore.singularize
|
150
|
+
|
151
|
+
# like_topic, follow_user
|
152
|
+
full_action_name = [action_type, action_name].join("_")
|
153
|
+
# like_user, follow_user
|
154
|
+
full_action_name_for_target = [action_type, "by", user_name].join("_")
|
155
|
+
# unlike_topic, unfollow_user
|
156
|
+
unaction_name = "un#{full_action_name}"
|
157
|
+
|
158
|
+
# @target.like_topic_actions, @target.follow_user_actions
|
159
|
+
has_many_name = [full_action_name, "actions"].join("_").to_sym
|
160
|
+
# @target.like_topics, @target.follow_users
|
161
|
+
has_many_through_name = full_action_name.pluralize.to_sym
|
162
|
+
|
163
|
+
# @user.like_by_user_actions, @user.follow_by_user_actions
|
164
|
+
has_many_name_for_target = [full_action_name_for_target, "actions"].join("_").to_sym
|
165
|
+
# @user.like_by_users, @user.follow_by_users
|
166
|
+
has_many_through_name_for_target = full_action_name_for_target.pluralize.to_sym
|
167
|
+
|
168
|
+
has_many_scope = lambda {
|
169
|
+
where(action_type: action_type, target_type: target_klass.name, user_type: user_klass.name)
|
170
|
+
}
|
171
|
+
|
172
|
+
# User has_many :like_topic_actions
|
173
|
+
user_klass.send :has_many, has_many_name, has_many_scope,
|
174
|
+
class_name: action_klass.name,
|
175
|
+
foreign_key: "user_id"
|
176
|
+
# User has_many :like_topics
|
177
|
+
user_klass.send :has_many, has_many_through_name,
|
178
|
+
through: has_many_name,
|
179
|
+
source: :target,
|
180
|
+
source_type: target_klass.name
|
181
|
+
|
182
|
+
# Topic has_many :like_user_actions
|
183
|
+
target_klass.send :has_many, has_many_name_for_target, has_many_scope,
|
184
|
+
foreign_key: :target_id,
|
185
|
+
class_name: action_klass.name
|
186
|
+
# Topic has_many :like_users
|
187
|
+
target_klass.send :has_many, has_many_through_name_for_target,
|
188
|
+
through: has_many_name_for_target,
|
189
|
+
source_type: user_klass.name,
|
190
|
+
source: :user
|
191
|
+
|
192
|
+
# @user.like_topic
|
193
|
+
user_klass.send(:define_method, full_action_name) do |target_or_id|
|
194
|
+
target_id = target_or_id.is_a?(target_klass) ? target_or_id.id : target_or_id
|
195
|
+
result = user_klass.create_action(action_type, target_type: target_klass.name,
|
203
196
|
target_id: target_id,
|
204
197
|
user: self)
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
# @user.unlike_topic
|
209
|
-
user_klass.send(:define_method, unaction_name) do |target_or_id|
|
210
|
-
target_id = target_or_id.is_a?(target_klass) ? target_or_id.id : target_or_id
|
211
|
-
result = user_klass.destroy_action(action_type, target_type: target_klass.name,
|
212
|
-
target_id: target_id,
|
213
|
-
user: self)
|
214
|
-
target_or_id.reload if target_or_id.is_a?(target_klass)
|
215
|
-
self.reload
|
216
|
-
result
|
217
|
-
end
|
198
|
+
target_or_id.reload if target_or_id.is_a?(target_klass)
|
199
|
+
reload
|
200
|
+
result
|
218
201
|
end
|
219
202
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
opts[:target_type] = opts[:target].class.name
|
228
|
-
opts[:target_id] = opts[:target].id
|
229
|
-
end
|
230
|
-
opts
|
203
|
+
# @user.like_topic?
|
204
|
+
user_klass.send(:define_method, "#{full_action_name}?") do |target_or_id|
|
205
|
+
target_id = target_or_id.is_a?(target_klass) ? target_or_id.id : target_or_id
|
206
|
+
result = user_klass.find_action(action_type, target_type: target_klass.name,
|
207
|
+
target_id: target_id,
|
208
|
+
user: self)
|
209
|
+
result.present?
|
231
210
|
end
|
232
211
|
|
233
|
-
|
234
|
-
|
212
|
+
# @user.unlike_topic
|
213
|
+
user_klass.send(:define_method, unaction_name) do |target_or_id|
|
214
|
+
target_id = target_or_id.is_a?(target_klass) ? target_or_id.id : target_or_id
|
215
|
+
result = user_klass.destroy_action(action_type, target_type: target_klass.name,
|
216
|
+
target_id: target_id,
|
217
|
+
user: self)
|
218
|
+
target_or_id.reload if target_or_id.is_a?(target_klass)
|
219
|
+
reload
|
220
|
+
result
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def safe_action_opts(opts)
|
225
|
+
opts ||= {}
|
226
|
+
if opts[:user]
|
227
|
+
opts[:user_id] = opts[:user].id
|
228
|
+
opts[:user_type] = opts[:user].class.name
|
229
|
+
end
|
230
|
+
if opts[:target]
|
231
|
+
opts[:target_type] = opts[:target].class.name
|
232
|
+
opts[:target_id] = opts[:target].id
|
235
233
|
end
|
234
|
+
opts
|
235
|
+
end
|
236
|
+
|
237
|
+
def where_opts(opts)
|
238
|
+
opts.extract!(:action_type, :target_type, :target_id, :user_id, :user_type)
|
239
|
+
end
|
236
240
|
end
|
237
241
|
end
|
238
242
|
end
|
data/lib/action_store/model.rb
CHANGED
data/lib/action_store/version.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "rails/generators"
|
3
4
|
module ActionStore
|
4
5
|
module Generators
|
5
6
|
class InstallGenerator < Rails::Generators::Base
|
6
7
|
desc "Create ActionStore's base files"
|
7
|
-
source_root File.expand_path("
|
8
|
+
source_root File.expand_path("../../..", __dir__)
|
8
9
|
|
9
10
|
def add_initializer
|
10
11
|
template "config/initializers/action_store.rb", "config/initializers/action_store.rb"
|
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: action-store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Lee
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2017-02-04 00:00:00.000000000 Z
|
@@ -16,22 +16,16 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '5'
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '7'
|
19
|
+
version: '5.2'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: '5'
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '7'
|
26
|
+
version: '5.2'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
28
|
+
name: codecov
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
36
30
|
requirements:
|
37
31
|
- - ">="
|
@@ -59,7 +53,7 @@ dependencies:
|
|
59
53
|
- !ruby/object:Gem::Version
|
60
54
|
version: '0'
|
61
55
|
- !ruby/object:Gem::Dependency
|
62
|
-
name:
|
56
|
+
name: pg
|
63
57
|
requirement: !ruby/object:Gem::Requirement
|
64
58
|
requirements:
|
65
59
|
- - ">="
|
@@ -73,7 +67,7 @@ dependencies:
|
|
73
67
|
- !ruby/object:Gem::Version
|
74
68
|
version: '0'
|
75
69
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
70
|
+
name: simplecov
|
77
71
|
requirement: !ruby/object:Gem::Requirement
|
78
72
|
requirements:
|
79
73
|
- - ">="
|
@@ -112,7 +106,7 @@ homepage: https://github.com/rails-engine/action-store
|
|
112
106
|
licenses:
|
113
107
|
- MIT
|
114
108
|
metadata: {}
|
115
|
-
post_install_message:
|
109
|
+
post_install_message:
|
116
110
|
rdoc_options: []
|
117
111
|
require_paths:
|
118
112
|
- lib
|
@@ -127,8 +121,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
121
|
- !ruby/object:Gem::Version
|
128
122
|
version: '0'
|
129
123
|
requirements: []
|
130
|
-
rubygems_version: 3.
|
131
|
-
signing_key:
|
124
|
+
rubygems_version: 3.2.3
|
125
|
+
signing_key:
|
132
126
|
specification_version: 4
|
133
127
|
summary: Store difference kind of actions (Like, Follow, Star, Block ...) in one table.
|
134
128
|
test_files: []
|