dynamic_scaffold 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +465 -0
- data/Rakefile +32 -0
- data/app/assets/config/dynamic_scaffold_manifest.js +0 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/README.md +9 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/angle-double-down.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/angle-double-up.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/chevron-down.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/chevron-left.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/chevron-right.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/chevron-up.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/exclamation-circle.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/hdd.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/pencil-alt.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/plus.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/step-backward.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/step-forward.svg +1 -0
- data/app/assets/images/dynamic_scaffold/fontawesome/times.svg +1 -0
- data/app/assets/javascripts/dynamic_scaffold/common.js +95 -0
- data/app/assets/javascripts/dynamic_scaffold/delete.js +57 -0
- data/app/assets/javascripts/dynamic_scaffold/pagination.js +26 -0
- data/app/assets/javascripts/dynamic_scaffold/sorter.js +120 -0
- data/app/assets/javascripts/dynamic_scaffold.js +4 -0
- data/app/assets/stylesheets/dynamic_scaffold/bootstrap3.scss +22 -0
- data/app/assets/stylesheets/dynamic_scaffold/bootstrap4.scss +34 -0
- data/app/assets/stylesheets/dynamic_scaffold/common.scss +130 -0
- data/app/assets/stylesheets/dynamic_scaffold/resplist.scss +155 -0
- data/app/views/dynamic_scaffold/bootstrap/_edit.html.erb +1 -0
- data/app/views/dynamic_scaffold/bootstrap/_form.html.erb +53 -0
- data/app/views/dynamic_scaffold/bootstrap/_list.html.erb +88 -0
- data/app/views/dynamic_scaffold/bootstrap/_new.html.erb +1 -0
- data/app/views/dynamic_scaffold/bootstrap/_pagination.html.erb +5 -0
- data/app/views/dynamic_scaffold/bootstrap/_save_order.html.erb +7 -0
- data/app/views/dynamic_scaffold/bootstrap/kaminari/_first_page.html.erb +7 -0
- data/app/views/dynamic_scaffold/bootstrap/kaminari/_gap.html.erb +3 -0
- data/app/views/dynamic_scaffold/bootstrap/kaminari/_last_page.html.erb +7 -0
- data/app/views/dynamic_scaffold/bootstrap/kaminari/_next_page.html.erb +7 -0
- data/app/views/dynamic_scaffold/bootstrap/kaminari/_page.html.erb +9 -0
- data/app/views/dynamic_scaffold/bootstrap/kaminari/_paginator.html.erb +17 -0
- data/app/views/dynamic_scaffold/bootstrap/kaminari/_prev_page.html.erb +7 -0
- data/config/locales/en.yml +19 -0
- data/config/locales/ja.yml +28 -0
- data/config/routes.rb +2 -0
- data/lib/dynamic_scaffold/config.rb +263 -0
- data/lib/dynamic_scaffold/controller.rb +116 -0
- data/lib/dynamic_scaffold/controller_utilities.rb +115 -0
- data/lib/dynamic_scaffold/engine.rb +18 -0
- data/lib/dynamic_scaffold/error/base.rb +6 -0
- data/lib/dynamic_scaffold/error/controller.rb +6 -0
- data/lib/dynamic_scaffold/error/invalid_icon.rb +6 -0
- data/lib/dynamic_scaffold/form/item/base.rb +106 -0
- data/lib/dynamic_scaffold/form/item/block.rb +16 -0
- data/lib/dynamic_scaffold/form/item/single_option.rb +21 -0
- data/lib/dynamic_scaffold/form/item/two_options.rb +28 -0
- data/lib/dynamic_scaffold/form/item/two_options_with_block.rb +19 -0
- data/lib/dynamic_scaffold/icons/fontawesome.rb +47 -0
- data/lib/dynamic_scaffold/list/item.rb +35 -0
- data/lib/dynamic_scaffold/routes.rb +23 -0
- data/lib/dynamic_scaffold/version.rb +3 -0
- data/lib/dynamic_scaffold.rb +12 -0
- data/lib/generators/dynamic_scaffold/USAGE +19 -0
- data/lib/generators/dynamic_scaffold/dynamic_scaffold_generator.rb +25 -0
- data/lib/generators/dynamic_scaffold/templates/controller.erb +100 -0
- data/lib/generators/dynamic_scaffold/templates/views/edit.erb +1 -0
- data/lib/generators/dynamic_scaffold/templates/views/index.erb +1 -0
- data/lib/generators/dynamic_scaffold/templates/views/new.erb +1 -0
- data/lib/tasks/dynamic_scaffold_tasks.rake +4 -0
- metadata +355 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 503b558204f2955326a5c0f2de8b6f53221a2d26
|
4
|
+
data.tar.gz: df41bb6e67d8199f9fa2eaea9b3a06efbac340e6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d57e575315a2c80f8e5d5595ca4b4ce06a4eb14c91d71e2c7a8d03693b882330ee1d42a934e7882597e4e276a45c6833e33e48be171e66b80a9eef5e9021e135
|
7
|
+
data.tar.gz: e665811c6ff308e2e40ccef3e33a98b7ccbf1757e27c9690062e5b9b7ad8e0607ff18941a134034684779196245983de5d0efd58cfd774f94e291ac2aa087fcd
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2017 Masamoto Miyata
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,465 @@
|
|
1
|
+
# DynamicScaffold
|
2
|
+
The Scaffold system which dynamically generates CRUD and sort functions.
|
3
|
+
|
4
|
+
## Feature
|
5
|
+
|
6
|
+
* This is generate the pages using same views dynamically.
|
7
|
+
* Support the responsive design and touch UI.
|
8
|
+
* Support sort and pagination.
|
9
|
+
* This has the views with the Twitter Bootstrap. Support bootstrap3/4.
|
10
|
+
* Customizable and flexible.
|
11
|
+
|
12
|
+
<img src="images/list_with_pager.png">
|
13
|
+
|
14
|
+
|
15
|
+
<img src="images/form.png">
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
Add this line to your application's Gemfile:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
gem 'dynamic_scaffold', '~> 0.1'
|
25
|
+
```
|
26
|
+
|
27
|
+
And then execute:
|
28
|
+
```bash
|
29
|
+
$ bundle
|
30
|
+
```
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
### Routes
|
35
|
+
|
36
|
+
Please call `dynamic_scaffold_for` method with the resource name.
|
37
|
+
|
38
|
+
```rb
|
39
|
+
# config/routes.rb
|
40
|
+
Rails.application.routes.draw do
|
41
|
+
dynamic_scaffold_for 'shops'
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
This will generate the following routes.
|
46
|
+
|
47
|
+
```
|
48
|
+
sort_or_destroy_controls_master_shops PATCH /:locale/controls/master/shops/sort_or_destroy(.:format) controls/shops#sort_or_destroy
|
49
|
+
controls_master_shops GET /:locale/controls/master/shops(.:format) controls/shops#index
|
50
|
+
POST /:locale/controls/master/shops(.:format) controls/shops#create
|
51
|
+
new_controls_master_shop GET /:locale/controls/master/shops/new(.:format) controls/shops#new
|
52
|
+
edit_controls_master_shop GET /:locale/controls/master/shops/:id/edit(.:format) controls/shops#edit
|
53
|
+
controls_master_shop PATCH /:locale/controls/master/shops/:id(.:format) controls/shops#update
|
54
|
+
PUT /:locale/controls/master/shops/:id(.:format) controls/shops#update
|
55
|
+
```
|
56
|
+
|
57
|
+
### Generate controller and views
|
58
|
+
|
59
|
+
First, you need a model of the target table. If you have not generate it yet, please generate the model.
|
60
|
+
|
61
|
+
```
|
62
|
+
rails generate model Shop
|
63
|
+
```
|
64
|
+
|
65
|
+
Next, execute the following command for generate the controller and views.
|
66
|
+
|
67
|
+
```
|
68
|
+
rails generate dynamic_scaffold shops
|
69
|
+
create app/controllers/shops_controller.rb
|
70
|
+
create app/views/shops/edit.html.erb
|
71
|
+
create app/views/shops/index.html.erb
|
72
|
+
create app/views/shops/new.html.erb
|
73
|
+
```
|
74
|
+
|
75
|
+
You can also specify namespaces and the model name if you want.
|
76
|
+
|
77
|
+
```
|
78
|
+
rails generate dynamic_scaffold namespace/plural_model
|
79
|
+
rails generate dynamic_scaffold namespace/controller Model
|
80
|
+
```
|
81
|
+
|
82
|
+
### Prepare CSS and Javascript
|
83
|
+
|
84
|
+
You need to load the files for CSS and Javascript. Currently, we support the Bootstrap 3 and Bootstrap 4.
|
85
|
+
|
86
|
+
```sass
|
87
|
+
# app/assets/stylesheets/application.scss
|
88
|
+
@import 'dynamic_scaffold/bootstrap3'
|
89
|
+
# or
|
90
|
+
@import 'dynamic_scaffold/bootstrap4'
|
91
|
+
```
|
92
|
+
|
93
|
+
```js
|
94
|
+
// app/assets/javascripts/application.js
|
95
|
+
//= require dynamic_scaffold
|
96
|
+
```
|
97
|
+
|
98
|
+
### Customization
|
99
|
+
|
100
|
+
You can customize each items in the block passed as dynamic_scaffold method argument.
|
101
|
+
|
102
|
+
```rb
|
103
|
+
# app/controllers/shops_controller.rb
|
104
|
+
class ShopController < ApplicationController
|
105
|
+
include DynamicScaffold::Controller
|
106
|
+
dynamic_scaffold Shop do |config|
|
107
|
+
# customize here
|
108
|
+
# `config` is DynamicScaffold::Config
|
109
|
+
end
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
113
|
+
#### Customize list
|
114
|
+
|
115
|
+
|
116
|
+
You can customize the list through the `DynamicScaffold::Config#list` property.
|
117
|
+
|
118
|
+
```rb
|
119
|
+
# app/controllers/shops_controller.rb
|
120
|
+
class ShopController < ApplicationController
|
121
|
+
include DynamicScaffold::Controller
|
122
|
+
dynamic_scaffold Shop do |config|
|
123
|
+
# You can set each title in the list through title method.
|
124
|
+
# Pass the attribute name,
|
125
|
+
# config.list.title(:name)
|
126
|
+
# or
|
127
|
+
# config.list.title do |record|
|
128
|
+
# record.name
|
129
|
+
# end
|
130
|
+
|
131
|
+
# First arg is attribute name of model.
|
132
|
+
# Last hash arg is given to HTML attributes options.
|
133
|
+
# `label` method change the label (I18n model attribute name is default).
|
134
|
+
config.list.item(:id, style: 'width: 80px').label('Number')
|
135
|
+
config.list.item :name, style: 'width: 120px'
|
136
|
+
|
137
|
+
# If you want to call a model method, specify the block.
|
138
|
+
config.list.item :updated_at, style: 'width: 180px' do |rec, name|
|
139
|
+
rec.fdate name, '%Y-%m-%d %H:%M:%S'
|
140
|
+
end
|
141
|
+
|
142
|
+
# The `label` method also accepts block.
|
143
|
+
config.list.item(:created_at, style: 'width: 180px').label 'Create Date' do |rec, name|
|
144
|
+
rec.fdate name, '%Y-%m-%d %H:%M:%S'
|
145
|
+
end
|
146
|
+
|
147
|
+
# The first argument can also be omitted, to display item that is not model attribute.
|
148
|
+
# The block is executed in the context of view, so you can call the method of view.
|
149
|
+
config.list.item do |rec, name|
|
150
|
+
link_to "Show #{rec.name}", controls_master_shops_path
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
```
|
155
|
+
|
156
|
+
#### Customize form
|
157
|
+
|
158
|
+
You can customize the form through the `DynamicScaffold::Config#form` property.
|
159
|
+
|
160
|
+
```rb
|
161
|
+
# app/controllers/shops_controller.rb
|
162
|
+
class ShopController < ApplicationController
|
163
|
+
include DynamicScaffold::Controller
|
164
|
+
dynamic_scaffold Shop do |config|
|
165
|
+
# config.form.item(type, name, html_attributes)
|
166
|
+
# or
|
167
|
+
# config.form.item(type, name, options, html_attributes)
|
168
|
+
#
|
169
|
+
# You can use form helper methods for type,
|
170
|
+
# text_field, check_box, radio_button, password_field, hidden_field, file_field, text_area, color_field,
|
171
|
+
# collection_check_boxes, collection_radio_buttons, collection_select, grouped_collection_select,
|
172
|
+
# time_select, date_select, datetime_select
|
173
|
+
|
174
|
+
|
175
|
+
# Default label is I18n model attribute name.
|
176
|
+
config.form.item :text_field, :name
|
177
|
+
# You can specify `label`.
|
178
|
+
config.form.item(:text_field, :name).label 'Shop Name'
|
179
|
+
# You can set default value for new action.
|
180
|
+
config.form.item(:text_field, :name).default('Foo Bar')
|
181
|
+
|
182
|
+
# If you use hidden_field, the label will also be hidden.
|
183
|
+
config.form.item :hidden_field, :id
|
184
|
+
# but if you specify the label explicitly it will be displayed.
|
185
|
+
config.form.item(:hidden_field, :id).label 'ID'
|
186
|
+
|
187
|
+
# Last hash arg is given to HTML attributes.
|
188
|
+
config.form.item :text_area, :memo, rows: 8
|
189
|
+
|
190
|
+
# Methods of the collection conform to the [ActionView::Helpers::FormBuilder](https://apidock.com/rails/ActionView/Helpers/FormBuilder) method.
|
191
|
+
config.form.item(:collection_select,
|
192
|
+
:category_id, Category.all, :id, :name, include_blank: 'Select Category'
|
193
|
+
)
|
194
|
+
config.form.item(:collection_check_boxes, :state_ids, State.all, :id, :name)
|
195
|
+
config.form.item(:collection_radio_buttons, :status, Shop.statuses.map{|k, v| [v, k.titleize]}, :first, :last)
|
196
|
+
|
197
|
+
# If you want to display more free form field, use block.
|
198
|
+
# The block is executed in the context of view, so you can call the method of view.
|
199
|
+
config.form.item :block, :free do |form, field|
|
200
|
+
content_tag :div, class: 'foobar' do
|
201
|
+
form.text_field field.name, class: 'foobar'
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# The label of block method also accepts block.
|
206
|
+
config.form.item(:block, :free).label 'Free Value' do |form, field|
|
207
|
+
content_tag :div, class: 'foobar' do
|
208
|
+
form.text_field field.name, class: 'foobar'
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# You can also add a note to the form field.
|
213
|
+
config.form.item(:text_field, :name).note do
|
214
|
+
content_tag :p do
|
215
|
+
out = []
|
216
|
+
out << 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
|
217
|
+
out << 'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
|
218
|
+
out << tag(:br)
|
219
|
+
out << 'Ut enim ad minim veniam, quis nostrud exercitation ullamco '
|
220
|
+
out << 'laboris nisi ut aliquip ex ea commodo consequat. '
|
221
|
+
out << tag(:br)
|
222
|
+
safe_join(out)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
```
|
228
|
+
|
229
|
+
### Sorting
|
230
|
+
|
231
|
+
You can sort records having integer column for order in the list page.
|
232
|
+
|
233
|
+
```rb
|
234
|
+
class CreateCountries < ActiveRecord::Migration[5.1]
|
235
|
+
def change
|
236
|
+
create_table :countries do |t|
|
237
|
+
t.string :name
|
238
|
+
t.integer :sequence
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
```
|
243
|
+
|
244
|
+
```
|
245
|
+
rails generate dynamic_scaffold countries
|
246
|
+
```
|
247
|
+
|
248
|
+
```rb
|
249
|
+
# app/controllers/countries_controller.rb
|
250
|
+
class CountriesController < ApplicationController
|
251
|
+
include DynamicScaffold::Controller
|
252
|
+
dynamic_scaffold Country do |config|
|
253
|
+
config.list.sorter sequence: :desc
|
254
|
+
...
|
255
|
+
```
|
256
|
+
|
257
|
+
<img src="images/sorter.gif">
|
258
|
+
|
259
|
+
### Pagination
|
260
|
+
|
261
|
+
You can enable pagination with [kaminari](https://github.com/kaminari/kaminari).
|
262
|
+
|
263
|
+
```rb
|
264
|
+
# app/controllers/shops_controller.rb
|
265
|
+
class ShopController < ApplicationController
|
266
|
+
include DynamicScaffold::Controller
|
267
|
+
dynamic_scaffold Shop do |config|
|
268
|
+
config.list.pagination per_page: 20
|
269
|
+
...
|
270
|
+
```
|
271
|
+
|
272
|
+
The following options are available for the pagination.
|
273
|
+
|
274
|
+
```
|
275
|
+
window: 0, # kaminari options
|
276
|
+
outer_window: 0, # kaminari options
|
277
|
+
left: 0, # kaminari options
|
278
|
+
right: 0, # kaminari options
|
279
|
+
param_name: :page, # kaminari options
|
280
|
+
total_count: true, # Whether to display total count and active page, like `2/102`.
|
281
|
+
end_buttons: true, # Whether to display buttons to the first and last page.
|
282
|
+
neighbor_buttons: true, # Whether to display buttons to the next and prev page.
|
283
|
+
gap_buttons: false, # Whether to display gap buttons.
|
284
|
+
highlight_current: false, # Whether to highlight the current page.
|
285
|
+
```
|
286
|
+
|
287
|
+
### Scoping
|
288
|
+
|
289
|
+
You can scoping for target items by url param.
|
290
|
+
|
291
|
+
For example, you create the Scaffold of users for each role.
|
292
|
+
```rb
|
293
|
+
create_table :users do |t|
|
294
|
+
t.string :email, null: false
|
295
|
+
t.string :encrypted_password, null: false
|
296
|
+
t.integer :role, limit: 2, null: false
|
297
|
+
end
|
298
|
+
|
299
|
+
class User < ApplicationRecord
|
300
|
+
enum role: { admin: 1, staff: 2, member: 3 }
|
301
|
+
end
|
302
|
+
```
|
303
|
+
|
304
|
+
Set the route as follows.
|
305
|
+
|
306
|
+
```rb
|
307
|
+
Rails.application.routes.draw do
|
308
|
+
dynamic_scaffold_for 'users/:role', controller: 'users', as: 'users', role: Regexp.new(User.roles.keys.join('|'))
|
309
|
+
end
|
310
|
+
```
|
311
|
+
|
312
|
+
```
|
313
|
+
sort_or_destroy_controls_master_users PATCH /:locale/controls/master/users/:role/sort_or_destroy(.:format) controls/users#sort_or_destroy {:role=>/admin|staff|member/}
|
314
|
+
controls_master_users GET /:locale/controls/master/users/:role(.:format) controls/users#index {:role=>/admin|staff|member/}
|
315
|
+
POST /:locale/controls/master/users/:role(.:format) controls/users#create {:role=>/admin|staff|member/}
|
316
|
+
new_controls_master_user GET /:locale/controls/master/users/:role/new(.:format) controls/users#new {:role=>/admin|staff|member/}
|
317
|
+
edit_controls_master_user GET /:locale/controls/master/users/:role/:id/edit(.:format) controls/users#edit {:role=>/admin|staff|member/}
|
318
|
+
controls_master_user PATCH /:locale/controls/master/users/:role/:id(.:format) controls/users#update {:role=>/admin|staff|member/}
|
319
|
+
PUT /:locale/controls/master/users/:role/:id(.:format) controls/users#update {:role=>/admin|staff|member/}
|
320
|
+
```
|
321
|
+
|
322
|
+
For the controller, as follows.
|
323
|
+
|
324
|
+
```rb
|
325
|
+
# app/controllers/users_controller.rb
|
326
|
+
class UsersController < ApplicationController
|
327
|
+
include DynamicScaffold::Controller
|
328
|
+
dynamic_scaffold User do |c|
|
329
|
+
c.scope [:role]
|
330
|
+
...
|
331
|
+
```
|
332
|
+
|
333
|
+
|
334
|
+
### View helper
|
335
|
+
|
336
|
+
#### dynamic_scaffold.title
|
337
|
+
|
338
|
+
|
339
|
+
You can set and get the title of the pages.
|
340
|
+
|
341
|
+
|
342
|
+
```erb
|
343
|
+
# app/views/your_resources/list.html.erb
|
344
|
+
<%= dynamic_scaffold.title.current.name %>
|
345
|
+
<!-- Shop -->
|
346
|
+
|
347
|
+
<%= dynamic_scaffold.title.current.action %>
|
348
|
+
<!-- List -->
|
349
|
+
|
350
|
+
<%= dynamic_scaffold.title.current.full %>
|
351
|
+
<!-- Shop List -->
|
352
|
+
```
|
353
|
+
|
354
|
+
You can get another action title through the action name method too.
|
355
|
+
|
356
|
+
```erb
|
357
|
+
# app/views/your_resources/list.html.erb
|
358
|
+
<%= dynamic_scaffold.title.new.full %>
|
359
|
+
<!-- Create Shop -->
|
360
|
+
```
|
361
|
+
|
362
|
+
If you want change from the model name, set `config.title.name`.
|
363
|
+
|
364
|
+
```rb
|
365
|
+
# app/controllers/shops_controller.rb
|
366
|
+
class ShopController < ApplicationController
|
367
|
+
include DynamicScaffold::Controller
|
368
|
+
dynamic_scaffold Shop do |config|
|
369
|
+
config.title.name = 'Model'
|
370
|
+
...
|
371
|
+
```
|
372
|
+
|
373
|
+
If you want to dynamically set according to url parameters, you can also use block.
|
374
|
+
|
375
|
+
```rb
|
376
|
+
# app/controllers/shops_controller.rb
|
377
|
+
class ShopController < ApplicationController
|
378
|
+
include DynamicScaffold::Controller
|
379
|
+
dynamic_scaffold Shop do |config|
|
380
|
+
config.title.name do |params|
|
381
|
+
I18n.t "enum.user.role.#{params[role]}", default: params[role].titleize
|
382
|
+
end
|
383
|
+
```
|
384
|
+
|
385
|
+
#### dynamic_scaffold_path
|
386
|
+
|
387
|
+
You can get the path by specifying the action name. Below is an example of displaying breadcrumbs.
|
388
|
+
|
389
|
+
```erb
|
390
|
+
<ol class="breadcrumb">
|
391
|
+
<%= yield :breadcrumb_before %>
|
392
|
+
<% if params['action'] == 'index' %>
|
393
|
+
<li class="active"><%= dynamic_scaffold.title.current.name %></li>
|
394
|
+
<% else %>
|
395
|
+
<li><%= link_to dynamic_scaffold.title.index.name, dynamic_scaffold_path(:index) %></li>
|
396
|
+
<li class="active"><%= dynamic_scaffold.title.current.action %></li>
|
397
|
+
<% end %>
|
398
|
+
</ol>
|
399
|
+
```
|
400
|
+
|
401
|
+
#### dynamic_scaffold.vars
|
402
|
+
|
403
|
+
You can cache, such as data to be displayed multiple times in a view using `dynamic_scaffold.vars`.
|
404
|
+
|
405
|
+
```rb
|
406
|
+
# app/controllers/shops_controller.rb
|
407
|
+
class ShopController < ApplicationController
|
408
|
+
include DynamicScaffold::Controller
|
409
|
+
dynamic_scaffold Shop do |config|
|
410
|
+
config.title.vars :shop_type do
|
411
|
+
ShopType.find(params['shop_type_id'])
|
412
|
+
end
|
413
|
+
...
|
414
|
+
```
|
415
|
+
|
416
|
+
```rb
|
417
|
+
# in your view
|
418
|
+
<%= dynamic_scaffold.vars.shop_type.name %>
|
419
|
+
```
|
420
|
+
|
421
|
+
### Password Handling Tips
|
422
|
+
|
423
|
+
Passwords are not displayed on the editing screen and should be skipped validation when sent with empty.
|
424
|
+
|
425
|
+
You can do it by preparing virtual attributes for the edit action, and switching between edit and new action.
|
426
|
+
|
427
|
+
```rb
|
428
|
+
class User < ApplicationRecord
|
429
|
+
validates :password, presence: true
|
430
|
+
|
431
|
+
attr_reader :password_edit
|
432
|
+
|
433
|
+
def password_edit=(value)
|
434
|
+
@password_edit = value
|
435
|
+
self.password = value if value.present?
|
436
|
+
end
|
437
|
+
end
|
438
|
+
```
|
439
|
+
|
440
|
+
```rb
|
441
|
+
class UsersController < ScaffoldController
|
442
|
+
include DynamicScaffold::Controller
|
443
|
+
dynamic_scaffold User do |config|
|
444
|
+
|
445
|
+
# If the block given to the `if` method returns false, the element is ignored.
|
446
|
+
# The block argument is `params` in controller.
|
447
|
+
config.form.item(:password_field, :password)
|
448
|
+
.if {|p| %w[new create].include? p[:action] }
|
449
|
+
|
450
|
+
# When you call the `proxy` method, the element's error messages and label will be used for the specified attribute.
|
451
|
+
config.form.item(:password_field, :password_edit)
|
452
|
+
.proxy(:password)
|
453
|
+
.if {|p| %w[edit update].include? p[:action] }
|
454
|
+
end
|
455
|
+
end
|
456
|
+
```
|
457
|
+
|
458
|
+
|
459
|
+
## Contributing
|
460
|
+
|
461
|
+
* We use rspec for test.
|
462
|
+
* Check code with [rubocop](https://github.com/bbatsov/rubocop).
|
463
|
+
|
464
|
+
## License
|
465
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
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 = 'DynamicScaffold'
|
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('../spec/dummy/Rakefile', __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
load 'rails/tasks/statistics.rake'
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'test'
|
28
|
+
t.pattern = 'test/**/*_test.rb'
|
29
|
+
t.verbose = false
|
30
|
+
end
|
31
|
+
|
32
|
+
task default: :test
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M143 256.3L7 120.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0L313 86.3c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.4 9.5-24.6 9.5-34 .1zm34 192l136-136c9.4-9.4 9.4-24.6 0-33.9l-22.6-22.6c-9.4-9.4-24.6-9.4-33.9 0L160 352.1l-96.4-96.4c-9.4-9.4-24.6-9.4-33.9 0L7 278.3c-9.4 9.4-9.4 24.6 0 33.9l136 136c9.4 9.5 24.6 9.5 34 .1z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M177 255.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 351.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 425.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1zm-34-192L7 199.7c-9.4 9.4-9.4 24.6 0 33.9l22.6 22.6c9.4 9.4 24.6 9.4 33.9 0l96.4-96.4 96.4 96.4c9.4 9.4 24.6 9.4 33.9 0l22.6-22.6c9.4-9.4 9.4-24.6 0-33.9l-136-136c-9.2-9.4-24.4-9.4-33.8 0z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M567.403 235.642L462.323 84.589A48 48 0 0 0 422.919 64H153.081a48 48 0 0 0-39.404 20.589L8.597 235.642A48.001 48.001 0 0 0 0 263.054V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V263.054c0-9.801-3-19.366-8.597-27.412zM153.081 112h269.838l77.913 112H75.168l77.913-112zM528 400H48V272h480v128zm-32-64c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32zm-96 0c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M64 468V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v176.4l195.5-181C352.1 22.3 384 36.6 384 64v384c0 27.4-31.9 41.7-52.5 24.6L136 292.7V468c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M384 44v424c0 6.6-5.4 12-12 12h-48c-6.6 0-12-5.4-12-12V291.6l-195.5 181C95.9 489.7 64 475.4 64 448V64c0-27.4 31.9-41.7 52.5-24.6L312 219.3V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12z"/></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"/></svg>
|