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 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
@@ -0,0 +1,10 @@
1
+ 0.2.0
2
+ -----
3
+
4
+ - New API, define action in User model.
5
+ - Builtin Many-to-Many relations and methods.
6
+
7
+ 0.1.0
8
+ -----
9
+
10
+ - First release.
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
+ [![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) [![Code Climate](https://codeclimate.com/github/rails-engine/action-store/badges/gpa.svg)](https://codeclimate.com/github/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) [![](http://inch-ci.org/github/rails-engine/action-store.svg?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,4 @@
1
+ # Auto generate with action-store gem.
2
+ class Action < ActiveRecord::Base
3
+ include ActionStore::Model
4
+ end
@@ -0,0 +1,3 @@
1
+ # ActionStore Config
2
+ ActionStore.configure do
3
+ end
@@ -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
@@ -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,4 @@
1
+ module ActionStore
2
+ class Configuration
3
+ end
4
+ end
@@ -0,0 +1,10 @@
1
+ module ActionStore
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace ActionStore
4
+
5
+ initializer "action_store.init_action", after: :load_config_initializers do
6
+ # Ensure eager_load Action model to init methods
7
+ require 'action'
8
+ end
9
+ end
10
+ end
@@ -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,11 @@
1
+ module ActionStore
2
+ module Model
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ # puts "Initalize ActionStore::Model"
7
+ belongs_to :target, polymorphic: true
8
+ belongs_to :user, polymorphic: true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module ActionStore
2
+ VERSION = "0.2.0"
3
+ 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: []