templaty 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +6 -0
- data/LICENSE +21 -0
- data/README.md +67 -0
- data/lib/generators/templaty/crud_generator.rb +179 -0
- data/lib/generators/templaty/migrations/add_column_generator.rb +102 -0
- data/lib/generators/templaty/templates/crud/app/assets/stylesheets/namespace/views/table/form.scss.erb +21 -0
- data/lib/generators/templaty/templates/crud/app/assets/stylesheets/namespace/views/table/index.scss.erb +3 -0
- data/lib/generators/templaty/templates/crud/app/assets/templates/namespace/table.gridy.hbs.erb +33 -0
- data/lib/generators/templaty/templates/crud/app/controllers/system/table_controller.rb.erb +71 -0
- data/lib/generators/templaty/templates/crud/app/javascripts/form.js.erb +24 -0
- data/lib/generators/templaty/templates/crud/app/javascripts/index.js.erb +48 -0
- data/lib/generators/templaty/templates/crud/app/models/model.rb.erb +41 -0
- data/lib/generators/templaty/templates/crud/app/views/namespace/table/_form.html.erb.erb +32 -0
- data/lib/generators/templaty/templates/crud/app/views/namespace/table/_submenu.html.erb.erb +5 -0
- data/lib/generators/templaty/templates/crud/app/views/namespace/table/_title.html.erb.erb +1 -0
- data/lib/generators/templaty/templates/crud/app/views/namespace/table/edit.html.erb.erb +14 -0
- data/lib/generators/templaty/templates/crud/app/views/namespace/table/gridy.json.jbuilder.erb +23 -0
- data/lib/generators/templaty/templates/crud/app/views/namespace/table/index.html.erb.erb +8 -0
- data/lib/generators/templaty/templates/crud/app/views/namespace/table/new.html.erb.erb +5 -0
- data/lib/generators/templaty/templates/crud/app/views/shared/icons/_model.html.erb.erb +1 -0
- data/lib/generators/templaty/templates/crud/config/locales/en/model.yml.erb +14 -0
- data/lib/generators/templaty/templates/crud/config/locales/en/namespace/table/create.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/en/namespace/table/destroy.yml.erb +6 -0
- data/lib/generators/templaty/templates/crud/config/locales/en/namespace/table/edit.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/en/namespace/table/index.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/en/namespace/table/show.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/en/namespace/table/update.yml.erb +6 -0
- data/lib/generators/templaty/templates/crud/config/locales/pt-BR/model.yml.erb +15 -0
- data/lib/generators/templaty/templates/crud/config/locales/pt-BR/namespace/table/create.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/pt-BR/namespace/table/destroy.yml.erb +6 -0
- data/lib/generators/templaty/templates/crud/config/locales/pt-BR/namespace/table/edit.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/pt-BR/namespace/table/index.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/pt-BR/namespace/table/show.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/pt-BR/namespace/table/update.yml.erb +7 -0
- data/lib/generators/templaty/templates/crud/config/locales/ru/model.yml.erb +14 -0
- data/lib/generators/templaty/templates/crud/config/locales/ru/namespace/table/create.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/ru/namespace/table/destroy.yml.erb +6 -0
- data/lib/generators/templaty/templates/crud/config/locales/ru/namespace/table/edit.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/ru/namespace/table/index.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/ru/namespace/table/show.yml.erb +5 -0
- data/lib/generators/templaty/templates/crud/config/locales/ru/namespace/table/update.yml.erb +6 -0
- data/lib/generators/templaty/templates/crud/db/seeds/pd/model.rb.erb +8 -0
- data/lib/generators/templaty/templates/crud/spec/controllers/namespace/model/create_spec.rb.erb +60 -0
- data/lib/generators/templaty/templates/crud/spec/controllers/namespace/model/destroy_spec.rb.erb +120 -0
- data/lib/generators/templaty/templates/crud/spec/controllers/namespace/model/edit_spec.rb.erb +43 -0
- data/lib/generators/templaty/templates/crud/spec/controllers/namespace/model/gridy/json_spec.rb.erb +52 -0
- data/lib/generators/templaty/templates/crud/spec/controllers/namespace/model/gridy/unlogged_spec.rb.erb +12 -0
- data/lib/generators/templaty/templates/crud/spec/controllers/namespace/model/index_spec.rb.erb +24 -0
- data/lib/generators/templaty/templates/crud/spec/controllers/namespace/model/new_spec.rb.erb +24 -0
- data/lib/generators/templaty/templates/crud/spec/controllers/namespace/model/update_spec.rb.erb +82 -0
- data/lib/generators/templaty/templates/crud/spec/features/namespace/model/create_spec.rb.erb +35 -0
- data/lib/generators/templaty/templates/crud/spec/features/namespace/model/destroy_spec.rb.erb +27 -0
- data/lib/generators/templaty/templates/crud/spec/features/namespace/model/gridy/initial_spec.rb.erb +53 -0
- data/lib/generators/templaty/templates/crud/spec/features/namespace/model/gridy/search_spec.rb.erb +46 -0
- data/lib/generators/templaty/templates/crud/spec/features/namespace/model/gridy/sort_spec.rb.erb +47 -0
- data/lib/generators/templaty/templates/crud/spec/features/namespace/model/update_spec.rb.erb +34 -0
- data/lib/generators/templaty/templates/crud/spec/models/model/list_spec.rb.erb +16 -0
- data/lib/generators/templaty/templates/db/migrate/add_column.rb.erb +7 -0
- data/lib/generators/templaty/templates/db/migrate/backfill.rb.erb +13 -0
- data/lib/generators/templaty/templates/db/migrate/not_null.rb.erb +7 -0
- data/lib/generators/templaty/templates/db/migrate/set_default.rb.erb +12 -0
- data/lib/generators/templaty/templates/db/migrate/validate_not_null.rb.erb +12 -0
- data/lib/templaty/helper.rb +131 -0
- data/lib/templaty/version.rb +5 -0
- data/lib/templaty.rb +5 -0
- metadata +208 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d99d9ee895e463e30ff91eefb57849bfc938fe908d7c2749d3491a2d4217adc9
|
4
|
+
data.tar.gz: 0ea5528ca6d086049bcd281941fa421ebebd0b93cd9ef589483a625078074296
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bcda9363dca4f149bb33d6111390a9f5c4f747e9d5bd5ca8f2f8e19015e5a21f3c109ea879302e7808fc144ca0dd8dbb4b62eccef71dc71a85e82df89a60d81d
|
7
|
+
data.tar.gz: bec92ad14dfdc8547d73924d29b5d1d58d1c59704a29a47f6499f3f68a075544ad13b35a14300673c684d60f9fdaeebe1a724be35e1b8b00dc29f25fde2ba0b6
|
data/CHANGELOG.md
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Washington Botelho
|
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
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Normalizy
|
2
|
+
|
3
|
+
[![CI](https://github.com/wbotelhos/templaty/workflows/CI/badge.svg)](https://github.com/wbotelhos/templaty/actions)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/templaty.svg)](https://badge.fury.io/rb/templaty)
|
5
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/f312587b4f126bb13e85/maintainability)](https://codeclimate.com/github/wbotelhos/templaty/maintainability)
|
6
|
+
[![Coverage](https://codecov.io/gh/wbotelhos/templaty/branch/main/graph/badge.svg)](https://codecov.io/gh/wbotelhos/templaty)
|
7
|
+
[![Sponsor](https://img.shields.io/badge/sponsor-%3C3-green)](https://www.patreon.com/wbotelhos)
|
8
|
+
|
9
|
+
Rails template generator
|
10
|
+
|
11
|
+
## Description
|
12
|
+
|
13
|
+
It's an opinated Rails' template generator.
|
14
|
+
|
15
|
+
## install
|
16
|
+
|
17
|
+
Add the following code on your `Gemfile` and run `bundle install`:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'templaty'
|
21
|
+
```
|
22
|
+
|
23
|
+
- [Adding a column with default value](#adding-a-column-with-default-value)
|
24
|
+
|
25
|
+
## Migrations
|
26
|
+
|
27
|
+
There are many templates to create safe migrations for you. The strategies are based on the gem [strong_migrations](https://github.com/ankane/strong_migrations). It's recommended use the gem and just take advantage of these templates.
|
28
|
+
|
29
|
+
### Adding a column with default value
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
rails g templaty:migrations:add_column \
|
33
|
+
--column=status \
|
34
|
+
--default=0 \
|
35
|
+
--null=false \
|
36
|
+
--rails_version=7.0 \
|
37
|
+
--table=discounts \
|
38
|
+
--type=integer
|
39
|
+
```
|
40
|
+
|
41
|
+
## CRUD
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
rails g templaty:crud \
|
45
|
+
--avatar=false \
|
46
|
+
--belongs_to=unit \
|
47
|
+
--cover=false \
|
48
|
+
--fields_grid=100,50:50 \
|
49
|
+
--fields_i18n=Nome,Porcentagem,Valor \
|
50
|
+
--fields_presence=name \
|
51
|
+
--fields=name,percentage_cents,amount_cents \
|
52
|
+
--gender=male \
|
53
|
+
--multipart=false \
|
54
|
+
--name_one=desconto \
|
55
|
+
--name_other=descontos \
|
56
|
+
--namespace_i18n=sistema \
|
57
|
+
--namespace=system \
|
58
|
+
--path=descontos \
|
59
|
+
--photos=false \
|
60
|
+
--show_route=false \
|
61
|
+
--table=discounts \
|
62
|
+
--validates_numericality=amount_cents:0:999_99,percentage_cents:0:100_00
|
63
|
+
```
|
64
|
+
|
65
|
+
## References
|
66
|
+
|
67
|
+
- [strong_migrations](https://github.com/ankane/strong_migrations)
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Templaty
|
4
|
+
class CrudGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('./templates', __dir__)
|
6
|
+
|
7
|
+
class_option :belongs_to, required: true, type: :string, desc: 'the belongs_to relation (user)'
|
8
|
+
class_option :fields_grid, required: true, type: :string, desc: 'The grid style for each field'
|
9
|
+
class_option :fields_i18n, required: true, type: :string, desc: 'Fields I18n (Nome,Descrição)'
|
10
|
+
class_option :fields_presence, required: true, type: :string, desc: 'Mandatory fields (name,total_cents)'
|
11
|
+
class_option :fields, required: true, type: :string, desc: 'Resource fields (description,name)'
|
12
|
+
class_option :gender, required: true, type: :string, desc: 'Resource gender (criada|criado com sucesso)'
|
13
|
+
class_option :name_one, required: true, type: :string, desc: 'Resource name on singular (discount)'
|
14
|
+
class_option :name_other, required: true, type: :string, desc: 'Resource name on plural (discounts)'
|
15
|
+
class_option :namespace_i18n, required: true, type: :string, desc: 'Template name translation (Sistema)'
|
16
|
+
class_option :namespace, required: true, type: :string, desc: 'Template name (admin, system...)'
|
17
|
+
class_option :path, required: true, type: :string, desc: 'Route path name (desconto)'
|
18
|
+
class_option :table, required: true, type: :string, desc: 'Table name (discounts)'
|
19
|
+
|
20
|
+
class_option :avatar, required: false, type: :boolean, default: false, desc: 'Has avatar? (true|false)'
|
21
|
+
class_option :cover, required: false, type: :boolean, default: false, desc: 'Has cover? (true|false)'
|
22
|
+
class_option :multipart, required: false, type: :boolean, default: false, desc: 'Multipart form? (true|false)'
|
23
|
+
class_option :photos, required: false, type: :boolean, default: false, desc: 'Has photos? (true|false)'
|
24
|
+
class_option :rails_version, required: false, type: :string, default: '6.1', desc: 'Rails version'
|
25
|
+
class_option :show_route, required: false, type: :boolean, default: false, desc: 'Add show route? (true|false)'
|
26
|
+
class_option :validates_numericality, required: false, type: :string, default: nil, desc: 'numericality validation (amount_cents:0:100_00)'
|
27
|
+
|
28
|
+
def controller
|
29
|
+
from = 'crud/app/controllers/system/table_controller.rb.erb'
|
30
|
+
to = "app/controllers/system/#{options[:table]}_controller.rb"
|
31
|
+
|
32
|
+
template(from, to)
|
33
|
+
end
|
34
|
+
|
35
|
+
def css
|
36
|
+
%w[form index].each do |name|
|
37
|
+
from = "crud/app/assets/stylesheets/namespace/views/table/#{name}.scss.erb"
|
38
|
+
to = "app/assets/stylesheets/#{options[:namespace]}/views/#{options[:table]}/#{name}.scss"
|
39
|
+
|
40
|
+
template(from, to)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def hbs
|
45
|
+
%w[table.gridy.hbs.erb].each do |name|
|
46
|
+
from = "crud/app/assets/templates/namespace/#{name}"
|
47
|
+
to = "app/javascript/templates/#{options[:namespace]}/#{options[:table]}.gridy.hbs"
|
48
|
+
|
49
|
+
template(from, to)
|
50
|
+
end
|
51
|
+
|
52
|
+
`gulp hbs`
|
53
|
+
end
|
54
|
+
|
55
|
+
def i18n
|
56
|
+
actions = %w[create destroy edit index show update]
|
57
|
+
|
58
|
+
%w[en pt-BR ru].each do |locale|
|
59
|
+
actions.each do |name|
|
60
|
+
next if name == 'show' && options[:show_route] != true
|
61
|
+
|
62
|
+
from = "crud/config/locales/#{locale}/namespace/table/#{name}.yml.erb"
|
63
|
+
to = "config/locales/#{locale}/#{options[:namespace]}/#{options[:table]}/#{name}.yml"
|
64
|
+
|
65
|
+
template(from, to)
|
66
|
+
end
|
67
|
+
|
68
|
+
from = "crud/config/locales/#{locale}/model.yml.erb"
|
69
|
+
to = "config/locales/#{locale}/#{options[:table].singularize}.yml"
|
70
|
+
|
71
|
+
template(from, to)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def js
|
76
|
+
%w[form index].each do |name|
|
77
|
+
from = "crud/app/javascripts/#{name}.js.erb"
|
78
|
+
to = "app/javascript/pages/#{options[:namespace]}/views/#{options[:table]}/#{name}.js"
|
79
|
+
|
80
|
+
template(from, to)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def model
|
85
|
+
from = 'crud/app/models/model.rb.erb'
|
86
|
+
to = "app/models/#{options[:table].singularize}.rb"
|
87
|
+
|
88
|
+
template(from, to)
|
89
|
+
end
|
90
|
+
|
91
|
+
def pages
|
92
|
+
%w[
|
93
|
+
_form.html.erb
|
94
|
+
_submenu.html.erb
|
95
|
+
_title.html.erb
|
96
|
+
edit.html.erb
|
97
|
+
gridy.json.jbuilder
|
98
|
+
index.html.erb
|
99
|
+
new.html.erb
|
100
|
+
].each do |name|
|
101
|
+
from = "crud/app/views/namespace/table/#{name}.erb"
|
102
|
+
to = "app/views/#{options[:namespace]}/#{options[:table]}/#{name}"
|
103
|
+
|
104
|
+
template(from, to)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def route_resource
|
109
|
+
content = <<~HEREDOC
|
110
|
+
resources :#{options[:table]},
|
111
|
+
concerns: :gridyable,
|
112
|
+
#{options[:show_route] ? nil : 'except: :show,'}
|
113
|
+
path: :#{options[:path]},
|
114
|
+
path_names: { new: :novo, edit: :editar }
|
115
|
+
HEREDOC
|
116
|
+
|
117
|
+
route content, namespace: options[:namespace]
|
118
|
+
end
|
119
|
+
|
120
|
+
def route_gridyable
|
121
|
+
route %(
|
122
|
+
concern :gridyable do
|
123
|
+
get :gridy, defaults: { format: :json }, on: :collection
|
124
|
+
end
|
125
|
+
)
|
126
|
+
end
|
127
|
+
|
128
|
+
def seed
|
129
|
+
from = 'crud/db/seeds/pd/model.rb.erb'
|
130
|
+
to = "db/seeds/pd/#{options[:table].singularize}.rb"
|
131
|
+
|
132
|
+
template(from, to)
|
133
|
+
end
|
134
|
+
|
135
|
+
def shared
|
136
|
+
%w[_model.html.erb].each do |name|
|
137
|
+
from = "crud/app/views/shared/icons/#{name}.erb"
|
138
|
+
to = "app/views/shared/guide/_#{options[:table].singularize}.html.erb"
|
139
|
+
|
140
|
+
template(from, to)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def spec
|
145
|
+
%w[
|
146
|
+
spec/controllers/namespace/model/create_spec.rb
|
147
|
+
spec/controllers/namespace/model/destroy_spec.rb
|
148
|
+
spec/controllers/namespace/model/edit_spec.rb
|
149
|
+
spec/controllers/namespace/model/gridy/json_spec.rb
|
150
|
+
spec/controllers/namespace/model/gridy/unlogged_spec.rb
|
151
|
+
spec/controllers/namespace/model/index_spec.rb
|
152
|
+
spec/controllers/namespace/model/new_spec.rb
|
153
|
+
spec/controllers/namespace/model/update_spec.rb
|
154
|
+
spec/features/namespace/model/create_spec.rb
|
155
|
+
spec/features/namespace/model/destroy_spec.rb
|
156
|
+
spec/features/namespace/model/gridy/initial_spec.rb
|
157
|
+
spec/features/namespace/model/gridy/search_spec.rb
|
158
|
+
spec/features/namespace/model/gridy/sort_spec.rb
|
159
|
+
spec/features/namespace/model/update_spec.rb
|
160
|
+
spec/models/model/list_spec.rb
|
161
|
+
].each do |path|
|
162
|
+
from = "crud/#{path}.erb"
|
163
|
+
to = path.sub('namespace', options[:namespace]).sub('model', options[:table].singularize)
|
164
|
+
|
165
|
+
template(from, to)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def warning
|
170
|
+
puts("\n=== Plese edit the following files: ===\n\n") # rubocop:disable Rails/Output
|
171
|
+
|
172
|
+
%w[en pt-BR ru].each do |locale|
|
173
|
+
puts("code config/locales/#{locale}/#{options[:table].singularize}.yml:5") # rubocop:disable Rails/Output
|
174
|
+
end
|
175
|
+
|
176
|
+
puts("code db/seeds/pd/#{options[:table].singularize}.rb") # rubocop:disable Rails/Output
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Templaty
|
4
|
+
module Migrations
|
5
|
+
class AddColumnGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('../templates', __dir__)
|
7
|
+
|
8
|
+
class_option :table, required: true, type: :string, desc: 'Table name'
|
9
|
+
class_option :column, required: true, type: :string, desc: 'Column name'
|
10
|
+
class_option :type, required: true, type: :string, desc: 'Column type'
|
11
|
+
|
12
|
+
class_option :default, required: false, type: :string, default: nil, desc: 'Column default value'
|
13
|
+
class_option :null, required: false, type: :boolean, default: nil, desc: 'Column accept null values?'
|
14
|
+
class_option :rails_version, required: false, type: :string, default: '6.1', desc: 'Rails version'
|
15
|
+
|
16
|
+
# Add the column without a default value.
|
17
|
+
#
|
18
|
+
# https://github.com/ankane/strong_migrations#good-1
|
19
|
+
#
|
20
|
+
def add_column
|
21
|
+
if options[:null] == false && options[:default].blank?
|
22
|
+
raise('[Templaty] Options "default" cannot be blank when option "null" is false.')
|
23
|
+
end
|
24
|
+
|
25
|
+
target = "db/migrate/#{timestamp(0)}_add_column_#{options[:column]}_to_#{options[:table]}.rb"
|
26
|
+
|
27
|
+
template('db/migrate/add_column.rb.erb', target)
|
28
|
+
|
29
|
+
`open #{target}`
|
30
|
+
end
|
31
|
+
|
32
|
+
# There are three keys to backfilling safely: batching, throttling, and running it outside a transaction.
|
33
|
+
# Use the Rails console or a separate migration with disable_ddl_transaction!.
|
34
|
+
#
|
35
|
+
# https://github.com/ankane/strong_migrations#good-2
|
36
|
+
#
|
37
|
+
def backfill
|
38
|
+
return unless options.key?(:default) || options[:null] != true # non declared null is `null: true`
|
39
|
+
|
40
|
+
target = "db/migrate/#{timestamp(1)}_backfill_#{options[:column]}_to_#{options[:table].pluralize}.rb"
|
41
|
+
|
42
|
+
template('db/migrate/backfill.rb.erb', target)
|
43
|
+
|
44
|
+
`open #{target}`
|
45
|
+
end
|
46
|
+
|
47
|
+
# Change the default.
|
48
|
+
# https://github.com/ankane/strong_migrations#good-1
|
49
|
+
#
|
50
|
+
def set_default
|
51
|
+
return unless options.key?(:default)
|
52
|
+
|
53
|
+
target = "db/migrate/#{timestamp(2)}_set_column_#{options[:column]}_default_to_#{options[:table].pluralize}.rb"
|
54
|
+
|
55
|
+
template('db/migrate/set_default.rb.erb', target)
|
56
|
+
|
57
|
+
`open #{target}`
|
58
|
+
end
|
59
|
+
|
60
|
+
# Add a check constraint.
|
61
|
+
#
|
62
|
+
# https://github.com/ankane/strong_migrations#good-11
|
63
|
+
#
|
64
|
+
def not_null
|
65
|
+
return unless options[:null] == false
|
66
|
+
|
67
|
+
target = "db/migrate/#{timestamp(3)}_not_null_#{options[:column]}_to_#{options[:table].pluralize}.rb"
|
68
|
+
|
69
|
+
template('db/migrate/not_null.rb.erb', target)
|
70
|
+
|
71
|
+
`open #{target}`
|
72
|
+
end
|
73
|
+
|
74
|
+
# Then validate it in a separate migration. A NOT NULL check constraint is functionally equivalent to
|
75
|
+
# setting NOT NULL on the column.
|
76
|
+
# In Postgres 12+, once the check constraint is validated, you can safely set NOT NULL on the column and drop
|
77
|
+
# the check constraint.
|
78
|
+
#
|
79
|
+
# https://github.com/ankane/strong_migrations#good-11
|
80
|
+
#
|
81
|
+
def validate_not_null
|
82
|
+
return unless options[:null] == false
|
83
|
+
|
84
|
+
target = "db/migrate/#{timestamp(4)}_validate_not_null_#{options[:column]}_to_#{options[:table].pluralize}.rb"
|
85
|
+
|
86
|
+
template('db/migrate/validate_not_null.rb.erb', target)
|
87
|
+
|
88
|
+
`open #{target}`
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def time
|
94
|
+
@time ||= Time.current
|
95
|
+
end
|
96
|
+
|
97
|
+
def timestamp(seconds)
|
98
|
+
(time + seconds.seconds).strftime('%Y%m%d%H%M%S')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<%- fields = Templaty::Helper.fields(options) -%>
|
2
|
+
<%- fields_grid = Templaty::Helper.fields_grid(options) -%>
|
3
|
+
<%- fields_grid_style = Templaty::Helper.fields_grid_style(options) -%>
|
4
|
+
[data-module~='<%= options[:namespace] %>.<%= options[:table] %>.form'] {
|
5
|
+
.container--form {
|
6
|
+
margin: 60px 16px;
|
7
|
+
}
|
8
|
+
|
9
|
+
<%- fields_grid.each.with_index do |numbers, grid_index| -%>
|
10
|
+
<%- numbers.each.with_index do |item, number_index| -%>
|
11
|
+
<%- field = fields[grid_index + number_index] -%>
|
12
|
+
<%- style = fields_grid_style[grid_index + number_index] -%>
|
13
|
+
.<%= field %> {
|
14
|
+
<%- style.each do |key, value| -%>
|
15
|
+
<%= key %>: <%= value %>;
|
16
|
+
<%- end -%>
|
17
|
+
}
|
18
|
+
|
19
|
+
<%- end -%>
|
20
|
+
<%- end -%>
|
21
|
+
}
|
data/lib/generators/templaty/templates/crud/app/assets/templates/namespace/table.gridy.hbs.erb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
<%- fields = Templaty::Helper.fields(options) -%>
|
2
|
+
{{#each list}}
|
3
|
+
<tr class="gridy__row">
|
4
|
+
<%- fields.each do |field| -%>
|
5
|
+
<td class="gridy__column">
|
6
|
+
<div class="gridy__column__text">{{<%= field.sub('_cents', '') %>}}</div>
|
7
|
+
</td>
|
8
|
+
|
9
|
+
<%- end -%>
|
10
|
+
|
11
|
+
<td class="gridy__column gridy__column--actions">
|
12
|
+
<div data-menu-actions class="menu-actions">
|
13
|
+
<div data-menu-actions-button class="menu-actions__button">
|
14
|
+
<img alt="" height="20" src="{{more_image}}" width="20">
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div class="menu-actions__body">
|
18
|
+
<ul role="menu" class="menu-actions__list">
|
19
|
+
<li class="menu-actions__item">
|
20
|
+
<a href="{{edit_path}}" title="{{i18n_capitalized 'edit'}}">{{i18n_capitalized 'edit'}}</a>
|
21
|
+
</li>
|
22
|
+
|
23
|
+
<%- if options[:show_route] -%>
|
24
|
+
<li class="menu-actions__item">
|
25
|
+
<a href="{{show_path}}" title="{{i18n_capitalized 'view'}}">{{i18n_capitalized 'view'}}</a>
|
26
|
+
</li>
|
27
|
+
<%- end -%>
|
28
|
+
</ul>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
</td>
|
32
|
+
</tr>
|
33
|
+
{{/each}}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module <%= options[:namespace].classify %>
|
4
|
+
class <%= options[:table].classify.pluralize %>Controller < <%= options[:namespace].classify %>::BaseController
|
5
|
+
before_action :authorizy
|
6
|
+
|
7
|
+
before_action :assign_record_for_action, only: %i[destroy edit update]
|
8
|
+
|
9
|
+
def create
|
10
|
+
@<%= options[:table].singularize %> = <%= options[:table].classify%>.new(create_params)
|
11
|
+
@<%= options[:table].singularize %>.unit_id = session[:current_unit_id]
|
12
|
+
|
13
|
+
if @<%= options[:table].singularize %>.save
|
14
|
+
redirect_to <%= options[:namespace] %>_<%= options[:table] %>_url, info: t('.success')
|
15
|
+
else
|
16
|
+
render :new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def destroy
|
21
|
+
if @<%= options[:table].singularize %>.destroy
|
22
|
+
redirect_to <%= options[:namespace] %>_<%= options[:table] %>_url, info: t('.success')
|
23
|
+
else
|
24
|
+
render :edit
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def edit; end
|
29
|
+
|
30
|
+
def gridy
|
31
|
+
lister = Lister
|
32
|
+
.new(self, params)
|
33
|
+
.init
|
34
|
+
.select(%i[id <%= Templaty::Helper.fields(options).sort.join(' ') %>])
|
35
|
+
.where(unit_id: session[:current_unit_id])
|
36
|
+
|
37
|
+
@items = lister.items
|
38
|
+
@total = lister.total
|
39
|
+
end
|
40
|
+
|
41
|
+
def index; end
|
42
|
+
|
43
|
+
def new
|
44
|
+
@<%= options[:table].singularize %> = <%= options[:table].classify%>.new
|
45
|
+
end
|
46
|
+
|
47
|
+
def update
|
48
|
+
if @<%= options[:table].singularize %>.update(update_params)
|
49
|
+
redirect_to <%= options[:namespace] %>_<%= options[:table] %>_url, info: t('.success')
|
50
|
+
else
|
51
|
+
render :edit
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def assign_record_for_action
|
58
|
+
@<%= options[:table].singularize %> = <%= options[:table].classify%>.where(unit_id: session[:current_unit_id]).findy(params[:id])
|
59
|
+
|
60
|
+
redirect_to <%= options[:namespace] %>_<%= options[:table] %>_url, info: t('.not_found') unless @<%= options[:table].singularize %>
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_params
|
64
|
+
params.require(:<%= options[:table].singularize %>).permit(<%= Templaty::Helper.fields(options).sort.map { |field| ":#{field}" }.join(', ') %>)
|
65
|
+
end
|
66
|
+
|
67
|
+
def update_params
|
68
|
+
params.require(:<%= options[:table].singularize %>).permit(<%= Templaty::Helper.fields(options).sort.map { |field| ":#{field}" }.join(', ') %>)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<% fields = Templaty::Helper.fields(options) -%>
|
2
|
+
import modulejs from 'modulejs';
|
3
|
+
|
4
|
+
<%- if fields.any? { |field| field.start_with?('percentage') || field.end_with?('_cents') } -%>
|
5
|
+
import Masker from '@/modules/masker';
|
6
|
+
<%- end -%>
|
7
|
+
|
8
|
+
modulejs.define('<%= options[:namespace] %>.<%= options[:table] %>.form', () => {
|
9
|
+
'use strict';
|
10
|
+
|
11
|
+
class <%= options[:namespace].classify %><%= options[:table].classify.pluralize %>Form {
|
12
|
+
create() {
|
13
|
+
<%- fields.sort.each do |field| -%>
|
14
|
+
<%- if field.start_with?('percentage') -%>
|
15
|
+
Masker.percentage(document.querySelector('[data-percentage]'));
|
16
|
+
<%- elsif field.end_with?('_cents') -%>
|
17
|
+
Masker.money(document.querySelector('[data-money]'));
|
18
|
+
<%- end -%>
|
19
|
+
<%- end -%>
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
return SystemDiscountsForm;
|
24
|
+
});
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<% fields = Templaty::Helper.fields(options) + ['menu'] -%>
|
2
|
+
import modulejs from 'modulejs';
|
3
|
+
|
4
|
+
import GridyCommon from '@/modules/gridy_common';
|
5
|
+
import HandlebarsHelpers from '@/modules/handlebars_helpers';
|
6
|
+
import I18n from '@/modules/i18n';
|
7
|
+
import MenuActions from '@/modules/menu_actions';
|
8
|
+
|
9
|
+
const Templates = require('@/pages/<%= options[:namespace] %>/templates');
|
10
|
+
|
11
|
+
modulejs.define('<%= options[:namespace] %>.<%= options[:table] %>.index', () => {
|
12
|
+
'use strict';
|
13
|
+
|
14
|
+
class <%= options[:namespace].classify %><%= options[:table].classify.pluralize %>Index {
|
15
|
+
constructor(options) {
|
16
|
+
this.grid = $('[data-gridy]');
|
17
|
+
this.options = options;
|
18
|
+
}
|
19
|
+
|
20
|
+
create() {
|
21
|
+
this.gridy();
|
22
|
+
|
23
|
+
HandlebarsHelpers.init();
|
24
|
+
}
|
25
|
+
|
26
|
+
gridy() {
|
27
|
+
GridyCommon.gridy(this.grid, {
|
28
|
+
find: 'name',
|
29
|
+
sortName: '<%= options[:table] %>.created_at',
|
30
|
+
sortOrder: 'desc',
|
31
|
+
template: Templates.<%= options[:table] %>.gridy,
|
32
|
+
url: this.options.gridy.url,
|
33
|
+
|
34
|
+
done() {
|
35
|
+
MenuActions.init();
|
36
|
+
},
|
37
|
+
|
38
|
+
headers: [
|
39
|
+
<%- fields.each do |field| -%>
|
40
|
+
{ name: I18n.t('gridy.headers.<%= field.sub('_cents', '') %>'), value: '<%= field == 'menu' ? nil : field %>' },
|
41
|
+
<%- end -%>
|
42
|
+
],
|
43
|
+
});
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
return <%= options[:namespace].classify %><%= options[:table].classify.pluralize %>Index;
|
48
|
+
});
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<%- belongs_to = Templaty::Helper.belongs_to(options).sort -%>
|
2
|
+
<%- fields = Templaty::Helper.fields(options).sort -%>
|
3
|
+
<%- validates_numericality = Templaty::Helper.validates_numericality(options) -%>
|
4
|
+
# frozen_string_literal: true
|
5
|
+
|
6
|
+
class <%= options[:table].classify%> < ApplicationRecord
|
7
|
+
include PgSearch::Model
|
8
|
+
|
9
|
+
pg_search_scope :list,
|
10
|
+
against: %i[<%= fields.join(' ') %>],
|
11
|
+
ignoring: :accents,
|
12
|
+
using: { tsearch: { prefix: true } }
|
13
|
+
|
14
|
+
idy
|
15
|
+
|
16
|
+
<%- fields.each do |field| -%>
|
17
|
+
<%- if field == 'description' -%>
|
18
|
+
normalizy :<%= field %>, with: :strip
|
19
|
+
<%- elsif field.end_with?('_cents') || field == 'percentage' -%>
|
20
|
+
normalizy :<%= field %>, with: { money: { type: :cents } }
|
21
|
+
<%- else -%>
|
22
|
+
normalizy :<%= field %>, with: :squish
|
23
|
+
<%- end -%>
|
24
|
+
<%- end -%>
|
25
|
+
|
26
|
+
<%- belongs_to.sort.each do |field| -%>
|
27
|
+
belongs_to :<%= field %>
|
28
|
+
<%- end -%>
|
29
|
+
|
30
|
+
<%- fields.each do |field| -%>
|
31
|
+
validates :<%= field %>, presence: true
|
32
|
+
<%- end -%>
|
33
|
+
|
34
|
+
<%- validates_numericality&.each do |field, values| -%>
|
35
|
+
validates :<%= field %>, numericality: {
|
36
|
+
greater_than_or_equal_to: <%= values[:min] %>,
|
37
|
+
less_than_or_equal_to: <%= values[:max] %>,
|
38
|
+
}
|
39
|
+
|
40
|
+
<%- end -%>
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<%- fields = Templaty::Helper.fields(options) -%>
|
2
|
+
<%- fields_grid = Templaty::Helper.fields_grid(options) -%>
|
3
|
+
<%%= render 'title' %>
|
4
|
+
|
5
|
+
<div class="box-content container--form container--form-top">
|
6
|
+
<%%= errors_for f.object %>
|
7
|
+
|
8
|
+
<div class="clearfix grid__collapse">
|
9
|
+
<%- fields_grid.each.with_index do |numbers, grid_index| -%>
|
10
|
+
<div class="form-grid">
|
11
|
+
<%- numbers.each.with_index do |item, number_index| -%>
|
12
|
+
<%- field = fields[grid_index + number_index] -%>
|
13
|
+
<div class="form-field <%= field %>">
|
14
|
+
<%%= f.label :<%= field %>, class: :form__label %>
|
15
|
+
<%- if field.start_with?('percentage_cents') -%>
|
16
|
+
<%%= percentage_field f, :<%= field %>, <%= (grid_index + number_index).zero? ? 'focus: true, ' : nil %>type: :cents, class: 'form__input form__input--fluid' %>
|
17
|
+
<%- elsif field.end_with?('_cents') -%>
|
18
|
+
<%%= money_field f, :<%= field %>, <%= (grid_index + number_index).zero? ? 'focus: true, ' : nil %>type: :cents, class: 'form__input form__input--fluid' %>
|
19
|
+
<%- else -%>
|
20
|
+
<%%= f.text_field :<%= field %>, <%= (grid_index + number_index).zero? ? 'focus: true, ' : nil %>placeholder: t('activerecord.attributes.<%= options[:table].singularize %>.<%= field %>'), class: 'form__input form__input--fluid' %>
|
21
|
+
<%- end -%>
|
22
|
+
<%%= f.errors_for :<%= field %> %>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<%- end -%>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<%- end -%>
|
29
|
+
</div>
|
30
|
+
|
31
|
+
<%%= render 'shared/guide/back_save_buttons', f: f %>
|
32
|
+
</div>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<%% content_for :ice_menu_subitems do %>
|
2
|
+
<%% if authorizy?('<%= options[:namespace] %>/<%= options[:table].singularize %>', :index) %>
|
3
|
+
<%%= render 'shared/ice_menu_subitem', href: <%= options[:namespace] %>_<%= options[:table].singularize %>_path, label: '<%= options[:table].singularize %>.index' %>
|
4
|
+
<%% end %>
|
5
|
+
<%% end %>
|