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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed5b51fa932124248255c6fd858b1030cdc27c0a7ec8a716147d68411d2b4d82
4
- data.tar.gz: 838a6621072a34b97137d63eaed9b97da9182d497da32a51783588ad8cc2bd04
3
+ metadata.gz: 394f0ac4dd31e9c98ae5052769ef935f67f8de6ab25401b34a529fd79fb5c7fd
4
+ data.tar.gz: 2682434ea7b22e756d5e78e4f97afb1986b75fe15f128668f9ce863c9c862616
5
5
  SHA512:
6
- metadata.gz: 0317b5ce5fc6119ed467292654bebf0c224a8892a29450f0ab9907062706df8e11728b610b4ed06ed5873ff2a049d922032b6134f91f3e6eec36af71fff18160
7
- data.tar.gz: 99b359f4bcd545392c0d68eb8ff9444ccd7e35c14f9803755e884ba710055a06e311651f5fbb0f8fbb7a00abc96573e5772cd863c2d3ce5a9a8078e2bec1bc08
6
+ metadata.gz: 06d674a641954289d95e8aa192608fa05ca9040a9a7eea1256c13b0b9499891a2486277b39371c73288fcc2f50922033a80016a22eeb2f7282978ff786f2ee2b
7
+ data.tar.gz: c550135c83fa5ec9c71ae993f87c3b5f9344a6dcbe175448365eecbbaee1f38e490b808096a506ea7209b61a1ad1e4e297a94dd052db5234e7bcda1d58c2a583
data/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
- 0.4.3
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
- [![Gem Version](https://badge.fury.io/rb/action-store.svg)](https://badge.fury.io/rb/action-store) [![Build Status](https://travis-ci.org/rails-engine/action-store.svg)](https://travis-ci.org/rails-engine/action-store) [![codecov.io](https://codecov.io/github/rails-engine/action-store/coverage.svg?branch=master)](https://codecov.io/github/rails-engine/action-store?branch=master)
3
+ [![Gem Version](https://badge.fury.io/rb/action-store.svg)](https://badge.fury.io/rb/action-store) [![build](https://github.com/rails-engine/action-store/workflows/build/badge.svg)](https://github.com/rails-engine/action-store/actions?query=workflow%3Abuild) [![codecov.io](https://codecov.io/github/rails-engine/action-store/coverage.svg?branch=master)](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 | Target Model | Target `counter_cache_field` | User `counter_cache_field` | Target has_many | User has_many |
65
- |----------------|--------------|------------------------------|----------------------------|-----------------|---------------|
66
- | `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` |
67
- | `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` |
68
- | `action_store :star, :project, class_name: 'Repository'` | `Repository ` | `stars_count` | `star_projects_count` | `has_many :star_by_user_actions`, `has_many :star_by_users` |
69
- | `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` |
70
- | `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` |
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/action.rb
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.followers_count_
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("../test/dummy/Rakefile", __FILE__)
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,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Auto generate with action-store gem.
3
4
  class Action < ActiveRecord::Base
4
5
  include ActionStore::Model
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # ActionStore Config
3
4
  ActionStore.configure do
4
5
  end
@@ -1,18 +1,19 @@
1
1
  # frozen_string_literal: true
2
- class CreateActions < ActiveRecord::Migration[5.0]
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.integer :target_id
9
- t.string :user_type
10
- t.integer :user_id
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, [:user_type, :user_id, :action_type]
16
- add_index :actions, [:target_type, :target_id, :action_type]
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
- class AddUniqueIndexToActions < ActiveRecord::Migration[5.0]
1
+ # frozen_string_literal: true
2
+
3
+ class AddUniqueIndexToActions < ActiveRecord::Migration[5.2]
2
4
  def change
3
- add_index :actions, [:action_type, :target_type, :target_id, :user_type, :user_id], unique: true, name: :uk_action_target_user
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
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module ActionStore
3
4
  class Configuration
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module ActionStore
3
4
  class Engine < ::Rails::Engine
4
5
  isolate_namespace ActionStore
@@ -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, opts = {})
36
- opts ||= {}
37
- klass_name = opts[:class_name] || name.to_s.classify
38
- target_klass = klass_name.constantize
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 opts[:counter_cache] == true
43
+ if counter_cache == true
41
44
  # @post.stars_count
42
- opts[:counter_cache] = "#{action_type.pluralize}_count"
45
+ counter_cache = "#{action_type.pluralize}_count"
43
46
  end
44
- if opts[:user_counter_cache] == true
47
+ if user_counter_cache == true
45
48
  # @user.star_posts_count
46
- opts[:user_counter_cache] = "#{action_type}_#{name.to_s.pluralize}_count"
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.to_s,
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: opts[:counter_cache],
56
- user_counter_cache: opts[: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(action)
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
- Action.find_by(where_opts(opts))
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 = Action.find_or_create_by!(where_opts(opts))
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 = Action.where(where_opts(opts)).take
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 = Action.where(where_opts(opts)).first
108
- return true if !action
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 = Action.where(
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 = Action.where(
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
- def define_relations(action)
138
- target_klass = action[:target_klass]
139
- action_type = action[:action_type]
140
- action_name = action[:action_name]
141
-
142
- user_klass = self
143
-
144
- # user, person
145
- user_name = user_klass.table_name.underscore.singularize
146
-
147
- # like_topic, follow_user
148
- full_action_name = [action_type, action_name].join("_")
149
- # like_user, follow_user
150
- full_action_name_for_target = [action_type, "by", user_name].join("_")
151
- # unlike_topic, unfollow_user
152
- unaction_name = "un#{full_action_name}"
153
-
154
- # @target.like_topic_actions, @target.follow_user_actions
155
- has_many_name = [full_action_name, "actions"].join("_").to_sym
156
- # @target.like_topics, @target.follow_users
157
- has_many_through_name = full_action_name.pluralize.to_sym
158
-
159
- # @user.like_by_user_actions, @user.follow_by_user_actions
160
- has_many_name_for_target = [full_action_name_for_target, "actions"].join("_").to_sym
161
- # @user.like_by_users, @user.follow_by_users
162
- has_many_through_name_for_target = full_action_name_for_target.pluralize.to_sym
163
-
164
- has_many_scope = -> {
165
- where(action_type: action_type, target_type: target_klass.name, user_type: user_klass.name)
166
- }
167
-
168
- # User has_many :like_topic_actions
169
- user_klass.send :has_many, has_many_name, has_many_scope,
170
- class_name: "Action",
171
- foreign_key: "user_id"
172
- # User has_many :like_topics
173
- user_klass.send :has_many, has_many_through_name,
174
- through: has_many_name,
175
- source: :target,
176
- source_type: target_klass.name
177
-
178
- # Topic has_many :like_user_actions
179
- target_klass.send :has_many, has_many_name_for_target, has_many_scope,
180
- foreign_key: :target_id,
181
- class_name: "Action"
182
- # Topic has_many :like_users
183
- target_klass.send :has_many, has_many_through_name_for_target,
184
- through: has_many_name_for_target,
185
- source_type: user_klass.name,
186
- source: :user
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
- result.present?
206
- end
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
- def safe_action_opts(opts)
221
- opts ||= {}
222
- if opts[:user]
223
- opts[:user_id] = opts[:user].id
224
- opts[:user_type] = opts[:user].class.name
225
- end
226
- if opts[:target]
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
- def where_opts(opts)
234
- opts.extract!(:action_type, :target_type, :target_id, :user_id, :user_type)
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
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module ActionStore
3
4
  module Model
4
5
  extend ActiveSupport::Concern
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module ActionStore
3
- VERSION = "0.4.4"
4
+ VERSION = "1.1.2"
4
5
  end
@@ -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("../../../../", __FILE__)
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: 0.4.4
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: mysql2
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: simplecov
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: codecov
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.0.1
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: []