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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +129 -9
  4. data/app/controllers/concerns/motor/current_user_method.rb +15 -0
  5. data/app/controllers/motor/api_base_controller.rb +11 -17
  6. data/app/controllers/motor/application_controller.rb +1 -0
  7. data/app/controllers/motor/assets_controller.rb +2 -2
  8. data/app/controllers/motor/icons_controller.rb +1 -1
  9. data/app/controllers/motor/ui_controller.rb +12 -4
  10. data/app/mailers/motor/alerts_mailer.rb +5 -5
  11. data/app/models/motor/alert.rb +1 -0
  12. data/app/models/motor/dashboard.rb +1 -0
  13. data/app/models/motor/form.rb +1 -0
  14. data/app/models/motor/query.rb +1 -0
  15. data/app/models/motor/resource.rb +1 -0
  16. data/app/models/motor/tag.rb +1 -1
  17. data/app/views/motor/alerts_mailer/alert_email.html.erb +1 -1
  18. data/app/views/motor/ui/show.html.erb +1 -1
  19. data/config/routes.rb +8 -9
  20. data/lib/generators/motor/templates/install.rb +74 -65
  21. data/lib/motor.rb +0 -1
  22. data/lib/motor/active_record_utils.rb +13 -1
  23. data/lib/motor/admin.rb +1 -1
  24. data/lib/motor/alerts/persistance.rb +4 -4
  25. data/lib/motor/alerts/scheduled_alerts_cache.rb +2 -1
  26. data/lib/motor/alerts/scheduler.rb +1 -1
  27. data/lib/motor/api_query/apply_scope.rb +1 -1
  28. data/lib/motor/api_query/build_json.rb +6 -6
  29. data/lib/motor/api_query/paginate.rb +1 -0
  30. data/lib/motor/api_query/search.rb +1 -7
  31. data/lib/motor/assets.rb +1 -1
  32. data/lib/motor/build_schema/find_display_column.rb +1 -0
  33. data/lib/motor/build_schema/find_icon.rb +9 -7
  34. data/lib/motor/build_schema/load_from_rails.rb +5 -2
  35. data/lib/motor/configs/build_ui_app_tag.rb +8 -7
  36. data/lib/motor/configs/load_from_cache.rb +19 -14
  37. data/lib/motor/configs/sync_from_hash.rb +1 -1
  38. data/lib/motor/configs/sync_with_remote.rb +1 -1
  39. data/lib/motor/configs/write_to_file.rb +1 -0
  40. data/lib/motor/dashboards/persistance.rb +4 -4
  41. data/lib/motor/forms/persistance.rb +4 -4
  42. data/lib/motor/queries/persistance.rb +4 -4
  43. data/lib/motor/queries/run_query.rb +3 -3
  44. data/lib/motor/tags.rb +2 -2
  45. data/lib/motor/tasks/motor.rake +4 -0
  46. data/lib/motor/version.rb +1 -1
  47. data/ui/dist/{main-c0cfd92d021794d8cf13.css.gz → main-36a9ee6a9b0427a77d87.css.gz} +0 -0
  48. data/ui/dist/main-36a9ee6a9b0427a77d87.js.gz +0 -0
  49. data/ui/dist/manifest.json +5 -5
  50. metadata +5 -4
  51. data/ui/dist/main-c0cfd92d021794d8cf13.js.gz +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c9b9e07d46ccb90c2b32def4d67841e5898a6c966377694d3f0984c4a816c71
4
- data.tar.gz: 22a9a172949c4276489da4be065ed5ae04a89902fadcc327853809cbf8e7cbfb
3
+ metadata.gz: e36dd42cf57e4b17340faac8ac91874566a5920dda51cd113b7e8ccb62c82756
4
+ data.tar.gz: d72fddef3740647b12ac5723e3512290b0bee08ebbba4448f2b214d6c0dffb2d
5
5
  SHA512:
6
- metadata.gz: d2062e9bb0b9573acc873f70736bacd6aa721dfda35e40583d8ea3871404203e2d8ea09fdb08de6f0100e81d12b72f2670e1c69fdc4cd94039b8820351d6b391
7
- data.tar.gz: 97920cbbf18eb72bc6d5e0d6c3513c14dfb3cd8b0b273bc5a67ca4945f54babc19577fab6fcd217813f72ef48dd3b07757387a323193a28a0b33b0d08472d562
6
+ metadata.gz: 0efa0fd91dff6a962b367acba95a56335231f11331ba37170ded4324bc370cf85fc239c2a816a48fc293bd742de60d36d4cf5e4947627578530d8776e0e71bca
7
+ data.tar.gz: f106c14a7453c8db2d5754ef1ad9f6e99ec1fef33a58dea6779bdb031eabf3e6adce90ca6f2227ac222e0603b982aa06532d97520351afe42f45a913f0fb3d22
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2021 Pete Matsyburka
1
+ Copyright (c) 2021 Pete Matsyburka <pete.matsy@gmail.com>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,9 +1,10 @@
1
- # Motor
1
+ # Motor Admin
2
2
 
3
- Admin UI and Business Analytics.
3
+ Low-code Admin panel and Business intelligence Rails engine **(no DSL - configurable from the UI)**.
4
4
 
5
- ## Usage
6
- How to use my plugin.
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
+ [![Admin Panel](https://user-images.githubusercontent.com/5418788/119318538-1f30e300-bc82-11eb-94a4-107c31c93b13.png)](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
- Or install it yourself as:
21
+ Create and run migration:
21
22
  ```bash
22
- $ gem install motor-admin
23
+ $ rails motor:install && rake db:migrate
23
24
  ```
24
25
 
25
- Create and run migration:
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
+ ![Resource settings](https://user-images.githubusercontent.com/5418788/119318569-2a840e80-bc82-11eb-9ba3-f3964eb6f997.png)
42
+
43
+ ![Settings UI](https://user-images.githubusercontent.com/5418788/119263883-90708780-bbe9-11eb-9f9f-f76fed0b7f27.png)
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
+ ![Custom actions](https://user-images.githubusercontent.com/5418788/119266132-3c1dd580-bbf2-11eb-9666-09e1640eaf7b.png)
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
+ ![Custom form](https://user-images.githubusercontent.com/5418788/119264008-1391dd80-bbea-11eb-9f14-cb405e77fb60.png)
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
+ ![SQL query](https://user-images.githubusercontent.com/5418788/119264127-84d19080-bbea-11eb-9903-ef465d1d2c97.png)
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
+ ![motor-visualization](https://user-images.githubusercontent.com/5418788/119264625-a2075e80-bbec-11eb-986c-6106dd6e47ce.png)
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
+ ![Dashboard](https://user-images.githubusercontent.com/5418788/119264726-f579ac80-bbec-11eb-852e-8055f8aba200.png)
76
+
77
+ SQL queries can be organized into dashboards to create a convenient representation of the data.
78
+
79
+ ### Email Alerts
80
+
81
+ ![Email alert](https://user-images.githubusercontent.com/5418788/119265049-feb74900-bbed-11eb-8070-bcc8d6113b9b.png)
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
+ ![Intelligence search](https://user-images.githubusercontent.com/5418788/119266559-eea26800-bbf3-11eb-8cb3-d0538aa386a9.png)
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
+ ![motor-mobile](https://user-images.githubusercontent.com/5418788/119269566-03392d00-bc01-11eb-9e9d-1f6a58fe0749.png)
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
- $ rails generate motor:install && rake db:migrate
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://opensource.org/licenses/MIT).
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
- klass = Class.new
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,5 +2,6 @@
2
2
 
3
3
  module Motor
4
4
  class ApplicationController < ActionController::Base
5
+ include Motor::CurrentUserMethod
5
6
  end
6
7
  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.values.include?(filename)
23
+ return [404, {}, ''] unless Motor::Assets.manifest.value?(filename)
24
24
 
25
25
  assign_headers(filename)
26
26
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Motor
4
4
  class IconsController < ApiBaseController
5
- CACHE_STORE = ActiveSupport::Cache::MemoryStore.new
5
+ CACHE_STORE = ActiveSupport::Cache::MemoryStore.new(coder: ActiveSupport::Cache::NullCoder)
6
6
 
7
7
  def index
8
8
  data = CACHE_STORE.fetch('icons') do
@@ -4,15 +4,23 @@ module Motor
4
4
  class UiController < ApplicationController
5
5
  layout 'motor/application'
6
6
 
7
- def index
8
- Motor.reload! if Motor.development?
7
+ helper_method :current_user
9
8
 
10
- Motor::Configs::SyncFromFile.call
9
+ def index
10
+ render_ui
11
+ end
11
12
 
12
- render :show
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['MOTOR_ADMIN_FROM_ADDRESS'].presence
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'].sub(/\Awww\./, '')}" if ENV['HOST'].present?
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[:host].blank?
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].sub(/\Awww\./, '')}"
47
+ "reports@#{Rails.application.config.action_mailer.default_url_options[:host].delete_prefix('www.')}"
48
48
  end
49
49
  end
50
50
  end
@@ -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) }
@@ -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) }
@@ -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) }
@@ -4,6 +4,7 @@ module Motor
4
4
  class Resource < ::Motor::ApplicationRecord
5
5
  audited
6
6
 
7
+ attribute :preferences, default: -> { HashWithIndifferentAccess.new }
7
8
  serialize :preferences, HashSerializer
8
9
  end
9
10
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Motor
4
4
  class Tag < ::Motor::ApplicationRecord
5
- has_many :taggable_tags
5
+ has_many :taggable_tags, dependent: :destroy
6
6
  end
7
7
  end
@@ -92,7 +92,7 @@
92
92
  <th><%= column[:name] %></th>
93
93
  <% end %>
94
94
  </tr>
95
- <% @query_result.data.first(100).each do |row| %>
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: 'api' do
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: 'ui' do
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, :string, null: false
5
- t.column :description, :string
6
- t.column :sql_body, :string, null: false
7
- t.column :preferences, :string, null: false, default: '{}'
8
- t.column :author_id, :integer
9
- t.column :author_type, :string
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 'lower(name)',
16
- name: 'motor_queries_lower_name_unique_index',
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, :string, null: false
23
- t.column :description, :string
24
- t.column :preferences, :string, null: false, default: '{}'
25
- t.column :author_id, :integer
26
- t.column :author_type, :string
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 'lower(title)',
33
- name: 'motor_dashboards_lower_title_unique_index',
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, :string, null: false
40
- t.column :description, :string
41
- t.column :api_path, :string, null: false
42
- t.column :http_method, :string, null: false
43
- t.column :preferences, :string, null: false, default: '{}'
44
- t.column :author_id, :integer
45
- t.column :author_type, :string
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 'lower(name)',
52
- name: 'motor_forms_lower_name_unique_index',
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, :string, null: false, index: { unique: true }
59
- t.column :preferences, :string, null: false, default: '{}'
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, :string, null: false, index: { unique: true }
68
- t.column :value, :string, null: false, default: '{}'
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, :string, null: false
78
- t.column :description, :string
79
- t.column :to_emails, :string, null: false
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, :string, null: false, default: '{}'
82
- t.column :author_id, :integer
83
- t.column :author_type, :string
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 'lower(name)',
90
- name: 'motor_alerts_lower_name_unique_index',
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, :string, null: false
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, :string, null: false
109
+ t.column :name, :text, null: false
106
110
 
107
111
  t.timestamps
108
112
 
109
- t.index 'lower(name)',
110
- name: 'motor_tags_lower_name_unique_index',
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, :integer, null: false
117
- t.column :taggable_type, :string, null: false
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, :integer
126
- t.column :auditable_type, :string
127
- t.column :associated_id, :integer
128
- t.column :associated_type, :string
129
- t.column :user_id, :integer
130
- t.column :user_type, :string
131
- t.column :username, :string
132
- t.column :action, :string
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, :integer, default: 0
135
- t.column :comment, :string
136
- t.column :remote_address, :string
137
- t.column :request_uuid, :string
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
- add_index :motor_audits, %i[associated_type associated_id], name: 'motor_auditable_associated_index'
143
- add_index :motor_audits, %i[user_id user_type], name: 'motor_auditable_user_index'
144
- add_index :motor_audits, :request_uuid
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