action-store 0.4.4 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
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: []