motor-admin 0.1.46 → 0.1.51
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/LICENSE +1 -1
- data/README.md +129 -9
- data/app/controllers/concerns/motor/current_user_method.rb +15 -0
- data/app/controllers/motor/api_base_controller.rb +11 -17
- data/app/controllers/motor/application_controller.rb +1 -0
- data/app/controllers/motor/assets_controller.rb +2 -2
- data/app/controllers/motor/icons_controller.rb +1 -1
- data/app/controllers/motor/ui_controller.rb +12 -4
- data/app/mailers/motor/alerts_mailer.rb +5 -5
- data/app/models/motor/alert.rb +1 -0
- data/app/models/motor/dashboard.rb +1 -0
- data/app/models/motor/form.rb +1 -0
- data/app/models/motor/query.rb +1 -0
- data/app/models/motor/resource.rb +1 -0
- data/app/models/motor/tag.rb +1 -1
- data/app/views/motor/alerts_mailer/alert_email.html.erb +1 -1
- data/app/views/motor/ui/show.html.erb +1 -1
- data/config/routes.rb +8 -9
- data/lib/generators/motor/templates/install.rb +74 -65
- data/lib/motor.rb +0 -1
- data/lib/motor/active_record_utils.rb +13 -1
- data/lib/motor/admin.rb +1 -1
- data/lib/motor/alerts/persistance.rb +4 -4
- data/lib/motor/alerts/scheduled_alerts_cache.rb +2 -1
- data/lib/motor/alerts/scheduler.rb +1 -1
- data/lib/motor/api_query/apply_scope.rb +1 -1
- data/lib/motor/api_query/build_json.rb +6 -6
- data/lib/motor/api_query/paginate.rb +1 -0
- data/lib/motor/api_query/search.rb +1 -7
- data/lib/motor/assets.rb +1 -1
- data/lib/motor/build_schema/find_display_column.rb +1 -0
- data/lib/motor/build_schema/find_icon.rb +9 -7
- data/lib/motor/build_schema/load_from_rails.rb +5 -2
- data/lib/motor/configs/build_ui_app_tag.rb +8 -7
- data/lib/motor/configs/load_from_cache.rb +19 -14
- data/lib/motor/configs/sync_from_hash.rb +1 -1
- data/lib/motor/configs/sync_with_remote.rb +1 -1
- data/lib/motor/configs/write_to_file.rb +1 -0
- data/lib/motor/dashboards/persistance.rb +4 -4
- data/lib/motor/forms/persistance.rb +4 -4
- data/lib/motor/queries/persistance.rb +4 -4
- data/lib/motor/queries/run_query.rb +3 -3
- data/lib/motor/tags.rb +2 -2
- data/lib/motor/tasks/motor.rake +4 -0
- data/lib/motor/version.rb +1 -1
- data/ui/dist/{main-c0cfd92d021794d8cf13.css.gz → main-36a9ee6a9b0427a77d87.css.gz} +0 -0
- data/ui/dist/main-36a9ee6a9b0427a77d87.js.gz +0 -0
- data/ui/dist/manifest.json +5 -5
- metadata +5 -4
- data/ui/dist/main-c0cfd92d021794d8cf13.js.gz +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e36dd42cf57e4b17340faac8ac91874566a5920dda51cd113b7e8ccb62c82756
|
4
|
+
data.tar.gz: d72fddef3740647b12ac5723e3512290b0bee08ebbba4448f2b214d6c0dffb2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0efa0fd91dff6a962b367acba95a56335231f11331ba37170ded4324bc370cf85fc239c2a816a48fc293bd742de60d36d4cf5e4947627578530d8776e0e71bca
|
7
|
+
data.tar.gz: f106c14a7453c8db2d5754ef1ad9f6e99ec1fef33a58dea6779bdb031eabf3e6adce90ca6f2227ac222e0603b982aa06532d97520351afe42f45a913f0fb3d22
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
# Motor
|
1
|
+
# ⚡ Motor Admin
|
2
2
|
|
3
|
-
Admin
|
3
|
+
Low-code Admin panel and Business intelligence Rails engine **(no DSL - configurable from the UI)**.
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
🤓 [Demo App](https://motor-admin.herokuapp.com/demo) | [Features overview](https://www.youtube.com/watch?v=ngVoci8Hll4&list=PLu7llEMh0KcOkR3Uy_RJT0cXPZQKAYVsq&index=1)
|
6
|
+
|
7
|
+
[](https://motor-admin.herokuapp.com/demo)
|
7
8
|
|
8
9
|
## Installation
|
9
10
|
Add this line to your application's Gemfile:
|
@@ -17,16 +18,135 @@ And then execute:
|
|
17
18
|
$ bundle install
|
18
19
|
```
|
19
20
|
|
20
|
-
|
21
|
+
Create and run migration:
|
21
22
|
```bash
|
22
|
-
$
|
23
|
+
$ rails motor:install && rake db:migrate
|
23
24
|
```
|
24
25
|
|
25
|
-
|
26
|
+
## Features
|
27
|
+
|
28
|
+
* [Customizable CRUD](#customizable-crud)
|
29
|
+
* [Custom actions](#custom-actions)
|
30
|
+
* [Forms builder](#forms-builder)
|
31
|
+
* [SQL queries](#sql-queries)
|
32
|
+
* [Data visualization](#data-visualization)
|
33
|
+
* [Dashboards](#dashboards)
|
34
|
+
* [Email alerts](#email-alerts)
|
35
|
+
* [Intelligence search](#intelligence-search)
|
36
|
+
* [Optimized for mobile](#optimized-for-mobile)
|
37
|
+
* [Configurations sync between environments](#configurations-sync)
|
38
|
+
|
39
|
+
### Customizable CRUD
|
40
|
+
|
41
|
+

|
42
|
+
|
43
|
+

|
44
|
+
|
45
|
+
Everything in the admin panel can be configured using intuitive settings UI, which can be opened via the icon in the top right corner.
|
46
|
+
|
47
|
+
Data displayed on the resource page can be completely custimized via [SQL queries](#sql-queries) and [dashboards](#dashboards) attached to the resource as a tab. Usually, queries used to display resource data should contain `{{resource_name_id}}` [variable](#sql-queries).
|
48
|
+
|
49
|
+
### Custom Actions
|
50
|
+
|
51
|
+

|
52
|
+
|
53
|
+
Custom resource actions can be added via Active Record method call, API endpoint, or [custom forms](#forms-builder). Also, it's possible to override default create/update/delete actions.
|
54
|
+
|
55
|
+
### Forms Builder
|
56
|
+
|
57
|
+

|
58
|
+
|
59
|
+
Values from the form fields can be used in API path via `{field_name}` syntax: `/api/some-endpoint/{resource_id}/apply`
|
60
|
+
|
61
|
+
### SQL Queries
|
62
|
+
|
63
|
+

|
64
|
+
|
65
|
+
Queries can include embeded variables via `{{variable}}` syntax ([mustache](https://mustache.github.io)). `{{#variable}} ... {{/variable}}` syntax allows to decide if conditions inside the scope should be included in the query.
|
66
|
+
|
67
|
+
### Data Visualization
|
68
|
+
|
69
|
+

|
70
|
+
|
71
|
+
Data from the SQL query can be represented as: [table](https://motor-admin.herokuapp.com/demo/queries/12), [number](https://motor-admin.herokuapp.com/demo/queries/6), [line chart](https://motor-admin.herokuapp.com/demo/queries/3), [bar chart](https://motor-admin.herokuapp.com/demo/queries/1), [pie chart](https://motor-admin.herokuapp.com/demo/queries/9), [funnel](https://motor-admin.herokuapp.com/demo/queries/7), [markdown](https://motor-admin.herokuapp.com/demo/queries/8)
|
72
|
+
|
73
|
+
### Dashboards
|
74
|
+
|
75
|
+

|
76
|
+
|
77
|
+
SQL queries can be organized into dashboards to create a convenient representation of the data.
|
78
|
+
|
79
|
+
### Email Alerts
|
80
|
+
|
81
|
+

|
82
|
+
|
83
|
+
Query data can be sent via email periodically using the alerts feature. Interval of the alert email can be specified using natural language, e.g., `every day at midnight`, `every Monday at 8 PM`, `every weekday at 6AM and 6PM`, `every minute`.
|
84
|
+
|
85
|
+
Sender address can be specified using `MOTOR_ALERTS_FROM_ADDRESS` environment variable.
|
86
|
+
|
87
|
+
### Intelligence Search
|
88
|
+
|
89
|
+

|
90
|
+
|
91
|
+
Intelligence search can be opened via the top right corner button or using <kbd>Cmd</kbd> + <kbd>P</kbd> shortcut.
|
92
|
+
|
93
|
+
|
94
|
+
### Optimized for Mobile
|
95
|
+
|
96
|
+

|
97
|
+
|
98
|
+
|
99
|
+
### Configurations Sync
|
100
|
+
|
101
|
+
All admin panel configurations are automatically stored in the `config/motor.yml` file. It's recommended to include this file in the application git repository to always have the admin panel configurations in sync across different local and remote environments.
|
102
|
+
|
103
|
+
It's possible to sync local development admin panel configurations with remote production application via `rake motor:sync` task:
|
104
|
+
|
105
|
+
```bash
|
106
|
+
MOTOR_SYNC_REMOTE_URL=https://remote-app-url/ MOTOR_SYNC_API_KEY=secure-random-string rake motor:sync
|
107
|
+
```
|
108
|
+
|
109
|
+
|
110
|
+
## Authentication
|
111
|
+
|
112
|
+
Admin panel can be secured with 'Basic authentication' by specifying `MOTOR_AUTH_USERNAME` and `MOTOR_AUTH_PASSWORD` environment variables.
|
113
|
+
|
114
|
+
Alternatively, it can be secured with [devise](https://github.com/heartcombo/devise/wiki/How-To:-Define-resource-actions-that-require-authentication-using-routes.rb) or any other authentication library used by the application:
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
authenticate :admin_user do
|
118
|
+
mount Motor::Admin => '/admin'
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
## Development
|
123
|
+
|
124
|
+
Start webpack dev server:
|
125
|
+
|
26
126
|
```bash
|
27
|
-
|
127
|
+
yarn install && yarn serve
|
28
128
|
```
|
29
129
|
|
130
|
+
Setup development database:
|
131
|
+
|
132
|
+
```bash
|
133
|
+
rake app:db:create && rake app:db:setup
|
134
|
+
```
|
135
|
+
|
136
|
+
Start example application in development mode:
|
137
|
+
|
138
|
+
```bash
|
139
|
+
MOTOR_DEVELOPMENT=true rails s
|
140
|
+
```
|
141
|
+
|
142
|
+
## Comming Soon
|
143
|
+
|
144
|
+
* User groups
|
145
|
+
* Row-level permissions
|
146
|
+
* Multiple databases
|
147
|
+
* NoSQL data sources
|
148
|
+
* Pro Bussines intelligence features
|
149
|
+
|
30
150
|
## License
|
31
151
|
|
32
|
-
The gem is available as open source under the terms of the [MIT License](https://
|
152
|
+
The gem is available as open source under the terms of the [MIT License](https://github.com/omohokcoj/motor-admin/blob/master/LICENSE).
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Motor
|
4
|
+
module CurrentUserMethod
|
5
|
+
def current_user
|
6
|
+
if defined?(current_admin)
|
7
|
+
current_admin
|
8
|
+
elsif defined?(current_admin_user)
|
9
|
+
current_admin_user
|
10
|
+
elsif defined?(super)
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -2,30 +2,24 @@
|
|
2
2
|
|
3
3
|
module Motor
|
4
4
|
class ApiBaseController < ActionController::API
|
5
|
+
include Motor::CurrentUserMethod
|
6
|
+
|
7
|
+
class CanCanAbilityManageAll
|
8
|
+
include CanCan::Ability
|
9
|
+
|
10
|
+
def initialize(_)
|
11
|
+
can :manage, :all
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
5
15
|
rescue_from StandardError do |e|
|
6
16
|
Rails.logger.error(e)
|
7
17
|
|
8
18
|
render json: { errors: [e.message] }, status: :internal_server_error
|
9
19
|
end
|
10
20
|
|
11
|
-
def current_user
|
12
|
-
if defined?(current_admin)
|
13
|
-
current_admin
|
14
|
-
elsif defined?(current_admin_user)
|
15
|
-
current_admin_user
|
16
|
-
elsif defined?(super)
|
17
|
-
super
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
21
|
def current_ability
|
22
|
-
|
23
|
-
klass.include(CanCan::Ability)
|
24
|
-
klass.define_method(:initialize) do |_user|
|
25
|
-
can :manage, :all
|
26
|
-
end
|
27
|
-
|
28
|
-
klass.new(current_user)
|
22
|
+
CanCanAbilityManageAll.new(current_user)
|
29
23
|
end
|
30
24
|
end
|
31
25
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Motor
|
4
4
|
class AssetsController < ActionController::Metal
|
5
|
-
CACHE_STORE = ActiveSupport::Cache::MemoryStore.new
|
5
|
+
CACHE_STORE = ActiveSupport::Cache::MemoryStore.new(coder: ActiveSupport::Cache::NullCoder)
|
6
6
|
|
7
7
|
GZIP_TYPES = [
|
8
8
|
'application/javascript',
|
@@ -20,7 +20,7 @@ module Motor
|
|
20
20
|
def show
|
21
21
|
filename = params[:filename]
|
22
22
|
|
23
|
-
return [404, {}, ''] unless Motor::Assets.manifest.
|
23
|
+
return [404, {}, ''] unless Motor::Assets.manifest.value?(filename)
|
24
24
|
|
25
25
|
assign_headers(filename)
|
26
26
|
|
@@ -4,15 +4,23 @@ module Motor
|
|
4
4
|
class UiController < ApplicationController
|
5
5
|
layout 'motor/application'
|
6
6
|
|
7
|
-
|
8
|
-
Motor.reload! if Motor.development?
|
7
|
+
helper_method :current_user
|
9
8
|
|
10
|
-
|
9
|
+
def index
|
10
|
+
render_ui
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
+
def new
|
14
|
+
render_ui
|
13
15
|
end
|
14
16
|
|
15
17
|
def show
|
18
|
+
render_ui
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def render_ui
|
16
24
|
Motor.reload! if Motor.development?
|
17
25
|
|
18
26
|
Motor::Configs::SyncFromFile.call
|
@@ -26,13 +26,13 @@ module Motor
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def from_address
|
29
|
-
from = ENV['
|
29
|
+
from = ENV['MOTOR_ALERTS_FROM_ADDRESS'].presence
|
30
30
|
|
31
31
|
from ||= application_mailer_default_from
|
32
32
|
from ||= mailer_config_from_address
|
33
|
-
from ||= "reports@#{ENV['HOST'].
|
33
|
+
from ||= "reports@#{ENV['HOST'].delete_prefix('www.')}" if ENV['HOST'].present?
|
34
34
|
|
35
|
-
from
|
35
|
+
from || 'reports@example.com'
|
36
36
|
end
|
37
37
|
|
38
38
|
def application_mailer_default_from
|
@@ -42,9 +42,9 @@ module Motor
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def mailer_config_from_address
|
45
|
-
return if Rails.application.config.action_mailer.default_url_options
|
45
|
+
return if Rails.application.config.action_mailer.default_url_options&.dig(:host).blank?
|
46
46
|
|
47
|
-
"reports@#{Rails.application.config.action_mailer.default_url_options[:host].
|
47
|
+
"reports@#{Rails.application.config.action_mailer.default_url_options[:host].delete_prefix('www.')}"
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
data/app/models/motor/alert.rb
CHANGED
@@ -11,6 +11,7 @@ module Motor
|
|
11
11
|
has_many :taggable_tags, as: :taggable, dependent: :destroy
|
12
12
|
has_many :tags, through: :taggable_tags, class_name: 'Motor::Tag'
|
13
13
|
|
14
|
+
attribute :preferences, default: -> { HashWithIndifferentAccess.new }
|
14
15
|
serialize :preferences, HashSerializer
|
15
16
|
|
16
17
|
scope :active, -> { where(deleted_at: nil) }
|
@@ -9,6 +9,7 @@ module Motor
|
|
9
9
|
has_many :taggable_tags, as: :taggable, dependent: :destroy
|
10
10
|
has_many :tags, through: :taggable_tags, class_name: 'Motor::Tag'
|
11
11
|
|
12
|
+
attribute :preferences, default: -> { HashWithIndifferentAccess.new }
|
12
13
|
serialize :preferences, HashSerializer
|
13
14
|
|
14
15
|
scope :active, -> { where(deleted_at: nil) }
|
data/app/models/motor/form.rb
CHANGED
@@ -9,6 +9,7 @@ module Motor
|
|
9
9
|
has_many :taggable_tags, as: :taggable, dependent: :destroy
|
10
10
|
has_many :tags, through: :taggable_tags, class_name: 'Motor::Tag'
|
11
11
|
|
12
|
+
attribute :preferences, default: -> { HashWithIndifferentAccess.new }
|
12
13
|
serialize :preferences, HashSerializer
|
13
14
|
|
14
15
|
scope :active, -> { where(deleted_at: nil) }
|
data/app/models/motor/query.rb
CHANGED
@@ -10,6 +10,7 @@ module Motor
|
|
10
10
|
has_many :tags, through: :taggable_tags, class_name: 'Motor::Tag'
|
11
11
|
has_many :alerts, dependent: :destroy
|
12
12
|
|
13
|
+
attribute :preferences, default: -> { HashWithIndifferentAccess.new }
|
13
14
|
serialize :preferences, HashSerializer
|
14
15
|
|
15
16
|
scope :active, -> { where(deleted_at: nil) }
|
data/app/models/motor/tag.rb
CHANGED
@@ -92,7 +92,7 @@
|
|
92
92
|
<th><%= column[:name] %></th>
|
93
93
|
<% end %>
|
94
94
|
</tr>
|
95
|
-
<% @query_result.data.first(
|
95
|
+
<% @query_result.data.first(40).each do |row| %>
|
96
96
|
<tr>
|
97
97
|
<% row.each do |col| %>
|
98
98
|
<td><%= col.respond_to?(:strftime) ? l(col, format: :long) : col.to_s.truncate(100) %></th>
|
@@ -1 +1 @@
|
|
1
|
-
<%= raw(Motor::Configs::BuildUiAppTag.call) %>
|
1
|
+
<%= raw(Motor::Configs::BuildUiAppTag.call(current_user)) %>
|
data/config/routes.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Motor::Admin.routes.draw do
|
4
4
|
namespace :motor, path: '' do
|
5
|
-
scope 'api', as:
|
5
|
+
scope 'api', as: :api do
|
6
6
|
resources :run_queries, only: %i[show create]
|
7
7
|
resources :send_alerts, only: %i[create]
|
8
8
|
resources :queries, only: %i[index show create update destroy]
|
@@ -34,16 +34,15 @@ Motor::Admin.routes.draw do
|
|
34
34
|
|
35
35
|
get '/', to: 'ui#show'
|
36
36
|
|
37
|
-
scope as:
|
37
|
+
scope as: :ui do
|
38
|
+
get '/data(/*path)', to: 'ui#index', as: :data
|
39
|
+
|
38
40
|
with_options controller: 'ui' do
|
39
|
-
resources :data, only: %i[index show],
|
40
|
-
param: 'path',
|
41
|
-
constraints: { path: /.+/ }
|
42
41
|
resources :reports, only: %i[index show]
|
43
|
-
resources :queries, only: %i[index show]
|
44
|
-
resources :dashboards, only: %i[index show]
|
45
|
-
resources :alerts, only: %i[index show]
|
46
|
-
resources :forms, only: %i[index show]
|
42
|
+
resources :queries, only: %i[index show new]
|
43
|
+
resources :dashboards, only: %i[index show new]
|
44
|
+
resources :alerts, only: %i[index show new]
|
45
|
+
resources :forms, only: %i[index show new]
|
47
46
|
end
|
48
47
|
end
|
49
48
|
end
|
@@ -1,62 +1,65 @@
|
|
1
1
|
class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
2
2
|
def self.up
|
3
3
|
create_table :motor_queries do |t|
|
4
|
-
t.column :name, :
|
5
|
-
t.column :description, :
|
6
|
-
t.column :sql_body, :
|
7
|
-
t.column :preferences, :
|
8
|
-
t.column :author_id, :
|
9
|
-
t.column :author_type, :
|
4
|
+
t.column :name, :text, null: false
|
5
|
+
t.column :description, :text
|
6
|
+
t.column :sql_body, :text, null: false
|
7
|
+
t.column :preferences, :text, null: false
|
8
|
+
t.column :author_id, :bigint
|
9
|
+
t.column :author_type, :text
|
10
10
|
t.column :deleted_at, :datetime
|
11
11
|
|
12
12
|
t.timestamps
|
13
13
|
|
14
14
|
t.index :updated_at
|
15
|
-
t.index '
|
16
|
-
name: '
|
15
|
+
t.index 'name',
|
16
|
+
name: 'motor_queries_name_unique_index',
|
17
17
|
unique: true,
|
18
|
-
where: 'deleted_at IS NULL'
|
18
|
+
where: 'deleted_at IS NULL',
|
19
|
+
length: { name: 255 }
|
19
20
|
end
|
20
21
|
|
21
22
|
create_table :motor_dashboards do |t|
|
22
|
-
t.column :title, :
|
23
|
-
t.column :description, :
|
24
|
-
t.column :preferences, :
|
25
|
-
t.column :author_id, :
|
26
|
-
t.column :author_type, :
|
23
|
+
t.column :title, :text, null: false
|
24
|
+
t.column :description, :text
|
25
|
+
t.column :preferences, :text, null: false
|
26
|
+
t.column :author_id, :bigint
|
27
|
+
t.column :author_type, :text
|
27
28
|
t.column :deleted_at, :datetime
|
28
29
|
|
29
30
|
t.timestamps
|
30
31
|
|
31
32
|
t.index :updated_at
|
32
|
-
t.index '
|
33
|
-
name: '
|
33
|
+
t.index 'title',
|
34
|
+
name: 'motor_dashboards_title_unique_index',
|
34
35
|
unique: true,
|
35
|
-
where: 'deleted_at IS NULL'
|
36
|
+
where: 'deleted_at IS NULL',
|
37
|
+
length: { title: 255 }
|
36
38
|
end
|
37
39
|
|
38
40
|
create_table :motor_forms do |t|
|
39
|
-
t.column :name, :
|
40
|
-
t.column :description, :
|
41
|
-
t.column :api_path, :
|
42
|
-
t.column :http_method, :
|
43
|
-
t.column :preferences, :
|
44
|
-
t.column :author_id, :
|
45
|
-
t.column :author_type, :
|
41
|
+
t.column :name, :text, null: false
|
42
|
+
t.column :description, :text
|
43
|
+
t.column :api_path, :text, null: false
|
44
|
+
t.column :http_method, :text, null: false
|
45
|
+
t.column :preferences, :text, null: false
|
46
|
+
t.column :author_id, :bigint
|
47
|
+
t.column :author_type, :text
|
46
48
|
t.column :deleted_at, :datetime
|
47
49
|
|
48
50
|
t.timestamps
|
49
51
|
|
50
52
|
t.index :updated_at
|
51
|
-
t.index '
|
52
|
-
name: '
|
53
|
+
t.index 'name',
|
54
|
+
name: 'motor_forms_name_unique_index',
|
53
55
|
unique: true,
|
54
|
-
where: 'deleted_at IS NULL'
|
56
|
+
where: 'deleted_at IS NULL',
|
57
|
+
length: { name: 255 }
|
55
58
|
end
|
56
59
|
|
57
60
|
create_table :motor_resources do |t|
|
58
|
-
t.column :name, :
|
59
|
-
t.column :preferences, :
|
61
|
+
t.column :name, :text, null: false, index: { unique: true, length: 255 }
|
62
|
+
t.column :preferences, :text, null: false
|
60
63
|
|
61
64
|
t.timestamps
|
62
65
|
|
@@ -64,8 +67,8 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
64
67
|
end
|
65
68
|
|
66
69
|
create_table :motor_configs do |t|
|
67
|
-
t.column :key, :
|
68
|
-
t.column :value, :
|
70
|
+
t.column :key, :text, null: false, index: { unique: true, length: 255 }
|
71
|
+
t.column :value, :text, null: false
|
69
72
|
|
70
73
|
t.timestamps
|
71
74
|
|
@@ -74,74 +77,80 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
74
77
|
|
75
78
|
create_table :motor_alerts do |t|
|
76
79
|
t.references :query, null: false, foreign_key: { to_table: :motor_queries }, index: true
|
77
|
-
t.column :name, :
|
78
|
-
t.column :description, :
|
79
|
-
t.column :to_emails, :
|
80
|
+
t.column :name, :text, null: false
|
81
|
+
t.column :description, :text
|
82
|
+
t.column :to_emails, :text, null: false
|
80
83
|
t.column :is_enabled, :boolean, null: false, default: true
|
81
|
-
t.column :preferences, :
|
82
|
-
t.column :author_id, :
|
83
|
-
t.column :author_type, :
|
84
|
+
t.column :preferences, :text, null: false
|
85
|
+
t.column :author_id, :bigint
|
86
|
+
t.column :author_type, :text
|
84
87
|
t.column :deleted_at, :datetime
|
85
88
|
|
86
89
|
t.timestamps
|
87
90
|
|
88
91
|
t.index :updated_at
|
89
|
-
t.index '
|
90
|
-
name: '
|
92
|
+
t.index 'name',
|
93
|
+
name: 'motor_alerts_name_unique_index',
|
91
94
|
unique: true,
|
92
|
-
where: 'deleted_at IS NULL'
|
95
|
+
where: 'deleted_at IS NULL',
|
96
|
+
length: { name: 255 }
|
93
97
|
end
|
94
98
|
|
95
99
|
create_table :motor_alert_locks do |t|
|
96
100
|
t.references :alert, null: false, foreign_key: { to_table: :motor_alerts }
|
97
|
-
t.column :lock_timestamp, :
|
101
|
+
t.column :lock_timestamp, :text, null: false
|
98
102
|
|
99
103
|
t.timestamps
|
100
104
|
|
101
|
-
t.index %i[alert_id lock_timestamp], unique: true
|
105
|
+
t.index %i[alert_id lock_timestamp], unique: true, length: { lock_timestamp: 255 }
|
102
106
|
end
|
103
107
|
|
104
108
|
create_table :motor_tags do |t|
|
105
|
-
t.column :name, :
|
109
|
+
t.column :name, :text, null: false
|
106
110
|
|
107
111
|
t.timestamps
|
108
112
|
|
109
|
-
t.index '
|
110
|
-
name: '
|
111
|
-
unique: true
|
113
|
+
t.index 'name',
|
114
|
+
name: 'motor_tags_name_unique_index',
|
115
|
+
unique: true,
|
116
|
+
length: { name: 255 }
|
112
117
|
end
|
113
118
|
|
114
119
|
create_table :motor_taggable_tags do |t|
|
115
120
|
t.references :tag, null: false, foreign_key: { to_table: :motor_tags }, index: true
|
116
|
-
t.column :taggable_id, :
|
117
|
-
t.column :taggable_type, :
|
121
|
+
t.column :taggable_id, :bigint, null: false
|
122
|
+
t.column :taggable_type, :text, null: false
|
118
123
|
|
119
124
|
t.index %i[taggable_id taggable_type tag_id],
|
120
125
|
name: 'motor_polymorphic_association_tag_index',
|
121
|
-
unique: true
|
126
|
+
unique: true,
|
127
|
+
length: { taggable_type: 255 }
|
122
128
|
end
|
123
129
|
|
124
130
|
create_table :motor_audits do |t|
|
125
|
-
t.column :auditable_id, :
|
126
|
-
t.column :auditable_type, :
|
127
|
-
t.column :associated_id, :
|
128
|
-
t.column :associated_type, :
|
129
|
-
t.column :user_id, :
|
130
|
-
t.column :user_type, :
|
131
|
-
t.column :username, :
|
132
|
-
t.column :action, :
|
131
|
+
t.column :auditable_id, :bigint
|
132
|
+
t.column :auditable_type, :text
|
133
|
+
t.column :associated_id, :bigint
|
134
|
+
t.column :associated_type, :text
|
135
|
+
t.column :user_id, :bigint
|
136
|
+
t.column :user_type, :text
|
137
|
+
t.column :username, :text
|
138
|
+
t.column :action, :text
|
133
139
|
t.column :audited_changes, :text
|
134
|
-
t.column :version, :
|
135
|
-
t.column :comment, :
|
136
|
-
t.column :remote_address, :
|
137
|
-
t.column :request_uuid, :
|
140
|
+
t.column :version, :bigint, default: 0
|
141
|
+
t.column :comment, :text
|
142
|
+
t.column :remote_address, :text
|
143
|
+
t.column :request_uuid, :text
|
138
144
|
t.column :created_at, :datetime
|
139
145
|
end
|
140
146
|
|
141
|
-
add_index :motor_audits, %i[auditable_type auditable_id version], name: 'motor_auditable_index'
|
142
|
-
|
143
|
-
add_index :motor_audits, %i[
|
144
|
-
|
147
|
+
add_index :motor_audits, %i[auditable_type auditable_id version], name: 'motor_auditable_index',
|
148
|
+
length: { auditable_type: 255 }
|
149
|
+
add_index :motor_audits, %i[associated_type associated_id], name: 'motor_auditable_associated_index',
|
150
|
+
length: { associated_type: 255 }
|
151
|
+
add_index :motor_audits, %i[user_id user_type], name: 'motor_auditable_user_index',
|
152
|
+
length: { user_type: 255 }
|
153
|
+
add_index :motor_audits, :request_uuid, length: { request_uuid: 255 }
|
145
154
|
add_index :motor_audits, :created_at
|
146
155
|
end
|
147
156
|
|