bullet_train-super_scaffolding 1.1.15 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/account/scaffolding/completely_concrete/tangible_things_controller.rb +3 -1
- data/app/controllers/api/v1/scaffolding/completely_concrete/tangible_things_controller.rb +73 -64
- data/app/helpers/super_scaffolding_helper.rb +7 -4
- data/app/views/account/scaffolding/absolutely_abstract/creative_concepts/_creative_concept.html.erb +19 -0
- data/app/views/account/scaffolding/absolutely_abstract/creative_concepts/_index.html.erb +5 -14
- data/app/views/account/scaffolding/absolutely_abstract/creative_concepts/show.html.erb +1 -1
- data/app/views/account/scaffolding/completely_concrete/tangible_things/_index.html.erb +5 -27
- data/app/views/account/scaffolding/completely_concrete/tangible_things/_tangible_thing.html.erb +30 -0
- data/app/views/api/v1/scaffolding/completely_concrete/tangible_things/_tangible_thing.json.jbuilder +2 -0
- data/lib/bullet_train/super_scaffolding/scaffolders/crud_field_scaffolder.rb +1 -1
- data/lib/bullet_train/super_scaffolding/scaffolders/crud_scaffolder.rb +3 -3
- data/lib/bullet_train/super_scaffolding/scaffolders/oauth_provider_scaffolder.rb +7 -1
- data/lib/bullet_train/super_scaffolding/version.rb +1 -1
- data/lib/bullet_train/terminal_commands.rb +5 -0
- data/lib/scaffolding/block_manipulator.rb +48 -1
- data/lib/scaffolding/class_names_transformer.rb +5 -0
- data/lib/scaffolding/transformer.rb +57 -18
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 167575ff368c6952598431b5dfc8e262746a5ff645c0e18900d3126f1f8472a3
|
4
|
+
data.tar.gz: 8e3fee7b5b4996401b7c6201b6b144589f0ddadf00dbfcd73a5762fc53261db3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e982e035723c9fd0b4dea89bf5067afd56027836a1514d2753e22fc14f04c4a892d5947cd570e76547d9d4b24214e31be449f80e2dabc453cadfa39c49c7da2
|
7
|
+
data.tar.gz: 73fab7774358693d8b5070cf035d8318b38e66fc7943dbc183e9fcfdef63579159668d1fe83f813bd8a67c412ba12ea4124a463456364583c9bc86459987131e
|
@@ -61,7 +61,9 @@ class Account::Scaffolding::CompletelyConcrete::TangibleThingsController < Accou
|
|
61
61
|
|
62
62
|
private
|
63
63
|
|
64
|
-
|
64
|
+
if defined?(Api::V1::ApplicationController)
|
65
|
+
include strong_parameters_from_api
|
66
|
+
end
|
65
67
|
|
66
68
|
def process_params(strong_params)
|
67
69
|
# 🚅 skip this section when scaffolding.
|
@@ -1,78 +1,87 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Api::V1::ApplicationController is in the starter repository and isn't
|
2
|
+
# needed for this package's unit tests, but our CI tests will try to load this
|
3
|
+
# class because eager loading is set to `true` when CI=true.
|
4
|
+
# We wrap this class in an `if` statement to circumvent this issue.
|
5
|
+
if defined?(Api::V1::ApplicationController)
|
6
|
+
class Api::V1::Scaffolding::CompletelyConcrete::TangibleThingsController < Api::V1::ApplicationController
|
7
|
+
account_load_and_authorize_resource :tangible_thing, through: :absolutely_abstract_creative_concept, through_association: :completely_concrete_tangible_things
|
3
8
|
|
4
|
-
|
5
|
-
|
6
|
-
|
9
|
+
# GET /api/v1/scaffolding/absolutely_abstract/creative_concepts/:absolutely_abstract_creative_concept_id/completely_concrete/tangible_things
|
10
|
+
def index
|
11
|
+
end
|
7
12
|
|
8
|
-
|
9
|
-
|
10
|
-
|
13
|
+
# GET /api/v1/scaffolding/completely_concrete/tangible_things/:id
|
14
|
+
def show
|
15
|
+
end
|
11
16
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
# POST /api/v1/scaffolding/absolutely_abstract/creative_concepts/:absolutely_abstract_creative_concept_id/completely_concrete/tangible_things
|
18
|
+
def create
|
19
|
+
if @tangible_thing.save
|
20
|
+
render :show, status: :created, location: [:api, :v1, @tangible_thing]
|
21
|
+
else
|
22
|
+
render json: @tangible_thing.errors, status: :unprocessable_entity
|
23
|
+
end
|
18
24
|
end
|
19
|
-
end
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
# PATCH/PUT /api/v1/scaffolding/completely_concrete/tangible_things/:id
|
27
|
+
def update
|
28
|
+
if @tangible_thing.update(tangible_thing_params)
|
29
|
+
render :show
|
30
|
+
else
|
31
|
+
render json: @tangible_thing.errors, status: :unprocessable_entity
|
32
|
+
end
|
27
33
|
end
|
28
|
-
end
|
29
34
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
# DELETE /api/v1/scaffolding/completely_concrete/tangible_things/:id
|
36
|
+
def destroy
|
37
|
+
@tangible_thing.destroy
|
38
|
+
end
|
34
39
|
|
35
|
-
|
40
|
+
private
|
36
41
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
42
|
+
module StrongParameters
|
43
|
+
# Only allow a list of trusted parameters through.
|
44
|
+
def tangible_thing_params
|
45
|
+
strong_params = params.require(:scaffolding_completely_concrete_tangible_thing).permit(
|
46
|
+
*permitted_fields,
|
47
|
+
# 🚅 skip this section when scaffolding.
|
48
|
+
:text_field_value,
|
49
|
+
:action_text_value,
|
50
|
+
:boolean_button_value,
|
51
|
+
:button_value,
|
52
|
+
:color_picker_value,
|
53
|
+
:cloudinary_image_value,
|
54
|
+
:date_field_value,
|
55
|
+
:date_and_time_field_value,
|
56
|
+
:date_and_time_field_value_time_zone,
|
57
|
+
:email_field_value,
|
58
|
+
:file_field_value,
|
59
|
+
:file_field_value_removal,
|
60
|
+
:option_value,
|
61
|
+
:password_field_value,
|
62
|
+
:phone_field_value,
|
63
|
+
:super_select_value,
|
64
|
+
:text_area_value,
|
65
|
+
# 🚅 stop any skipping we're doing now.
|
66
|
+
# 🚅 super scaffolding will insert new fields above this line.
|
67
|
+
*permitted_arrays,
|
68
|
+
# 🚅 skip this section when scaffolding.
|
69
|
+
multiple_button_values: [],
|
70
|
+
multiple_option_values: [],
|
71
|
+
multiple_super_select_values: []
|
72
|
+
# 🚅 stop any skipping we're doing now.
|
73
|
+
# 🚅 super scaffolding will insert new arrays above this line.
|
74
|
+
)
|
70
75
|
|
71
|
-
|
76
|
+
process_params(strong_params)
|
72
77
|
|
73
|
-
|
78
|
+
strong_params
|
79
|
+
end
|
74
80
|
end
|
75
|
-
end
|
76
81
|
|
77
|
-
|
82
|
+
include StrongParameters
|
83
|
+
end
|
84
|
+
else
|
85
|
+
class Api::V1::Scaffolding::CompletelyConcrete::TangibleThingsController
|
86
|
+
end
|
78
87
|
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
module SuperScaffoldingHelper
|
2
2
|
unless defined?(BulletTrain::ActionModels)
|
3
|
+
# action_model_select_controller is originally a method
|
4
|
+
# in the Action Models package, but we can't simply
|
5
|
+
# remove this method from Super Scaffolded index partials
|
6
|
+
# when the package isn't present. Since we keep
|
7
|
+
# action_model_select_controller in our views, we need
|
8
|
+
# this method so we don't get a NoMethodError.
|
3
9
|
def action_model_select_controller
|
4
|
-
|
5
|
-
tag.div do
|
6
|
-
yield
|
7
|
-
end
|
10
|
+
yield
|
8
11
|
end
|
9
12
|
end
|
10
13
|
end
|
data/app/views/account/scaffolding/absolutely_abstract/creative_concepts/_creative_concept.html.erb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
<% context ||= @team %>
|
2
|
+
<% hide_actions ||= false %>
|
3
|
+
<% hide_back ||= false %>
|
4
|
+
|
5
|
+
<% with_attribute_settings object: creative_concept do %>
|
6
|
+
<tr data-id="<%= creative_concept.id %>">
|
7
|
+
<td><%= render 'shared/attributes/text', attribute: :name, url: [:account, creative_concept] %></td>
|
8
|
+
<td><%= render 'account/shared/memberships/photos', memberships: creative_concept.all_collaborators, size: 9, align: :center %></td>
|
9
|
+
<%# 🚅 super scaffolding will insert new fields above this line. %>
|
10
|
+
<td><%= display_date_and_time(creative_concept.created_at) %></td>
|
11
|
+
<td class="buttons">
|
12
|
+
<% unless hide_actions %>
|
13
|
+
<%# We write the full path here since this partial is called from different scopes. %>
|
14
|
+
<%= link_to t('account.scaffolding.absolutely_abstract.creative_concepts.buttons.shorthand.edit'), [:edit, :account, creative_concept], class: 'button-secondary button-smaller' if can? :edit, creative_concept %>
|
15
|
+
<%= button_to t('account.scaffolding.absolutely_abstract.creative_concepts.buttons.shorthand.destroy'), [:account, creative_concept], method: :delete, data: { confirm: t('account.scaffolding.absolutely_abstract.creative_concepts.buttons.confirmations.destroy', model_locales(creative_concept)) }, class: 'button-secondary button-smaller' if can? :destroy, creative_concept %>
|
16
|
+
<% end %>
|
17
|
+
</td>
|
18
|
+
</tr>
|
19
|
+
<% end %>
|
@@ -1,7 +1,11 @@
|
|
1
|
+
<% creative_concepts = creative_concepts.accessible_by(current_ability) %>
|
1
2
|
<% context ||= @team %>
|
2
3
|
<% hide_actions ||= false %>
|
3
4
|
<% hide_back ||= false %>
|
4
5
|
|
6
|
+
<% pagy ||= nil %>
|
7
|
+
<% pagy, creative_concepts = pagy(creative_concepts, page_param: :creative_concepts_page) unless pagy %>
|
8
|
+
|
5
9
|
<%= updates_for context, :scaffolding_absolutely_abstract_creative_concepts do %>
|
6
10
|
<%= render 'account/shared/box' do |p| %>
|
7
11
|
<% p.content_for :title, t(".contexts.#{context.class.name.underscore}.header") %>
|
@@ -24,20 +28,7 @@
|
|
24
28
|
</thead>
|
25
29
|
<tbody>
|
26
30
|
<% creative_concepts.each do |creative_concept| %>
|
27
|
-
|
28
|
-
<tr data-id="<%= creative_concept.id %>">
|
29
|
-
<td><%= render 'shared/attributes/text', attribute: :name, url: [:account, creative_concept] %></td>
|
30
|
-
<td><%= render 'account/shared/memberships/photos', memberships: creative_concept.all_collaborators, size: 9, align: :center %></td>
|
31
|
-
<%# 🚅 super scaffolding will insert new fields above this line. %>
|
32
|
-
<td><%= display_date_and_time(creative_concept.created_at) %></td>
|
33
|
-
<td class="buttons">
|
34
|
-
<% unless hide_actions %>
|
35
|
-
<%= link_to t('.buttons.shorthand.edit'), [:edit, :account, creative_concept], class: 'button-secondary button-smaller' if can? :edit, creative_concept %>
|
36
|
-
<%= button_to t('.buttons.shorthand.destroy'), [:account, creative_concept], method: :delete, data: { confirm: t('.buttons.confirmations.destroy', model_locales(creative_concept)) }, class: 'button-secondary button-smaller' if can? :destroy, creative_concept %>
|
37
|
-
<% end %>
|
38
|
-
</td>
|
39
|
-
</tr>
|
40
|
-
<% end %>
|
31
|
+
<%= render 'account/scaffolding/absolutely_abstract/creative_concepts/creative_concept', creative_concept: creative_concept %>
|
41
32
|
<% end %>
|
42
33
|
</tbody>
|
43
34
|
</table>
|
@@ -54,7 +54,7 @@
|
|
54
54
|
<% end %>
|
55
55
|
<% end %>
|
56
56
|
|
57
|
-
<%= render 'account/scaffolding/completely_concrete/tangible_things/index', tangible_things: @creative_concept.completely_concrete_tangible_things
|
57
|
+
<%= render 'account/scaffolding/completely_concrete/tangible_things/index', tangible_things: @creative_concept.completely_concrete_tangible_things, hide_back: true %>
|
58
58
|
|
59
59
|
<% if can? :read, Scaffolding::AbsolutelyAbstract::CreativeConcepts::Collaborator.new(creative_concept: @creative_concept) %>
|
60
60
|
<%= render 'account/scaffolding/absolutely_abstract/creative_concepts/collaborators/index', collaborators: @creative_concept.collaborators, hide_back: true %>
|
@@ -1,14 +1,15 @@
|
|
1
|
+
<% tangible_things = tangible_things.accessible_by(current_ability) %>
|
1
2
|
<% absolutely_abstract_creative_concept = @absolutely_abstract_creative_concept || @creative_concept %>
|
2
3
|
<% context ||= absolutely_abstract_creative_concept %>
|
3
4
|
<% collection ||= :completely_concrete_tangible_things %>
|
4
5
|
<% hide_actions ||= false %>
|
5
6
|
<% hide_back ||= false %>
|
6
7
|
|
7
|
-
<%
|
8
|
-
<% pagy, tangible_things = pagy(tangible_things, page_param: :tangible_things_page) %>
|
8
|
+
<% pagy ||= nil %>
|
9
|
+
<% pagy, tangible_things = pagy(tangible_things, page_param: :tangible_things_page) unless pagy %>
|
9
10
|
|
10
11
|
<%= action_model_select_controller do %>
|
11
|
-
|
12
|
+
<% updates_for context, collection do %>
|
12
13
|
<%= render 'account/shared/box', pagy: pagy do |p| %>
|
13
14
|
<% p.content_for :title, t(".contexts.#{context.class.name.underscore}.header") %>
|
14
15
|
<% p.content_for :description do %>
|
@@ -35,30 +36,7 @@
|
|
35
36
|
</thead>
|
36
37
|
<tbody>
|
37
38
|
<% tangible_things.each do |tangible_thing| %>
|
38
|
-
|
39
|
-
<tr data-id="<%= tangible_thing.id %>">
|
40
|
-
<%= render "shared/tables/checkbox", object: tangible_thing %>
|
41
|
-
<%# 🚅 skip this section when scaffolding. %>
|
42
|
-
<td><%= render 'shared/attributes/text', attribute: :text_field_value, url: [:account, tangible_thing] %></td>
|
43
|
-
<td><%= render 'shared/attributes/boolean', attribute: :boolean_button_value %></td>
|
44
|
-
<td><%= render 'shared/attributes/option', attribute: :button_value %></td>
|
45
|
-
<td><%= render 'shared/attributes/options', attribute: :multiple_button_values %></td>
|
46
|
-
<%# 🚅 stop any skipping we're doing now. %>
|
47
|
-
<%# 🚅 super scaffolding will insert new fields above this line. %>
|
48
|
-
<td><%= render 'shared/attributes/date_and_time', attribute: :created_at %></td>
|
49
|
-
<td class="buttons">
|
50
|
-
<% unless hide_actions %>
|
51
|
-
<% if can? :edit, tangible_thing %>
|
52
|
-
<%= link_to t('.buttons.shorthand.edit'), [:edit, :account, tangible_thing], class: 'button-secondary button-smaller' %>
|
53
|
-
<% end %>
|
54
|
-
<% if can? :destroy, tangible_thing %>
|
55
|
-
<%= button_to t('.buttons.shorthand.destroy'), [:account, tangible_thing], method: :delete, data: { confirm: t('.buttons.confirmations.destroy', model_locales(tangible_thing)) }, class: 'button-secondary button-smaller' %>
|
56
|
-
<% end %>
|
57
|
-
<%# 🚅 super scaffolding will insert new action model buttons above this line. %>
|
58
|
-
<% end %>
|
59
|
-
</td>
|
60
|
-
</tr>
|
61
|
-
<% end %>
|
39
|
+
<%= render 'account/scaffolding/completely_concrete/tangible_things/tangible_thing', tangible_thing: tangible_thing %>
|
62
40
|
<% end %>
|
63
41
|
</tbody>
|
64
42
|
</table>
|
data/app/views/account/scaffolding/completely_concrete/tangible_things/_tangible_thing.html.erb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
<% absolutely_abstract_creative_concept = @absolutely_abstract_creative_concept || @creative_concept %>
|
2
|
+
<% context ||= absolutely_abstract_creative_concept %>
|
3
|
+
<% collection ||= :completely_concrete_tangible_things %>
|
4
|
+
<% hide_actions ||= false %>
|
5
|
+
<% hide_back ||= false %>
|
6
|
+
|
7
|
+
<% with_attribute_settings object: tangible_thing do %>
|
8
|
+
<tr data-id="<%= tangible_thing.id %>">
|
9
|
+
<%= render "shared/tables/checkbox", object: tangible_thing %>
|
10
|
+
<%# 🚅 skip this section when scaffolding. %>
|
11
|
+
<td><%= render 'shared/attributes/text', attribute: :text_field_value, url: [:account, tangible_thing] %></td>
|
12
|
+
<td><%= render 'shared/attributes/boolean', attribute: :boolean_button_value %></td>
|
13
|
+
<td><%= render 'shared/attributes/option', attribute: :button_value %></td>
|
14
|
+
<td><%= render 'shared/attributes/options', attribute: :multiple_button_values %></td>
|
15
|
+
<%# 🚅 stop any skipping we're doing now. %>
|
16
|
+
<%# 🚅 super scaffolding will insert new fields above this line. %>
|
17
|
+
<td><%= render 'shared/attributes/date_and_time', attribute: :created_at %></td>
|
18
|
+
<td class="buttons">
|
19
|
+
<% unless hide_actions %>
|
20
|
+
<% if can? :edit, tangible_thing %>
|
21
|
+
<%= link_to t('.buttons.shorthand.edit'), [:edit, :account, tangible_thing], class: 'button-secondary button-smaller' %>
|
22
|
+
<% end %>
|
23
|
+
<% if can? :destroy, tangible_thing %>
|
24
|
+
<%= button_to t('.buttons.shorthand.destroy'), [:account, tangible_thing], method: :delete, data: { confirm: t('.buttons.confirmations.destroy', model_locales(tangible_thing)) }, class: 'button-secondary button-smaller' %>
|
25
|
+
<% end %>
|
26
|
+
<%# 🚅 super scaffolding will insert new action model buttons above this line. %>
|
27
|
+
<% end %>
|
28
|
+
</td>
|
29
|
+
</tr>
|
30
|
+
<% end %>
|
@@ -9,7 +9,7 @@ module BulletTrain
|
|
9
9
|
puts ""
|
10
10
|
puts "E.g. add a description and body to Pages:"
|
11
11
|
puts " rails g migration add_description_etc_to_pages description:text body:text"
|
12
|
-
puts " bin/super-scaffold crud-field Page description:
|
12
|
+
puts " bin/super-scaffold crud-field Page description:text_area body:text_area"
|
13
13
|
puts ""
|
14
14
|
puts "Options:"
|
15
15
|
puts ""
|
@@ -9,18 +9,18 @@ module BulletTrain
|
|
9
9
|
puts ""
|
10
10
|
puts "E.g. a Team has many Sites with some attributes:"
|
11
11
|
puts " rails g model Site team:references name:string url:text"
|
12
|
-
puts " bin/super-scaffold crud Site Team name:
|
12
|
+
puts " bin/super-scaffold crud Site Team name:text_field url:text_area"
|
13
13
|
puts ""
|
14
14
|
puts "E.g. a Section belongs to a Page, which belongs to a Site, which belongs to a Team:"
|
15
15
|
puts " rails g model Section page:references title:text body:text"
|
16
|
-
puts " bin/super-scaffold crud Section Page,Site,Team title:
|
16
|
+
puts " bin/super-scaffold crud Section Page,Site,Team title:text_area body:text_area"
|
17
17
|
puts ""
|
18
18
|
puts "E.g. an Image belongs to either a Page or a Site:"
|
19
19
|
puts " Doable! See https://bit.ly/2NvO8El for a step by step guide."
|
20
20
|
puts ""
|
21
21
|
puts "E.g. Pages belong to a Site and are sortable via drag-and-drop:"
|
22
22
|
puts " rails g model Page site:references name:string path:text"
|
23
|
-
puts " bin/super-scaffold crud Page Site,Team name:
|
23
|
+
puts " bin/super-scaffold crud Page Site,Team name:text_field path:text_area --sortable"
|
24
24
|
puts ""
|
25
25
|
puts "🏆 Protip: Commit your other changes before running Super Scaffolding so it's easy to undo if you (or we) make any mistakes."
|
26
26
|
puts "If you do that, you can reset to your last commit state by using `git checkout .` and `git clean -d -f` ."
|
@@ -61,7 +61,13 @@ module BulletTrain
|
|
61
61
|
puts "When you find one you like, hover your mouse over it and then come back here and"
|
62
62
|
puts "and enter the name of the icon you want to use."
|
63
63
|
response = $stdin.gets.chomp
|
64
|
-
TerminalCommands.
|
64
|
+
if TerminalCommands.can_open?
|
65
|
+
TerminalCommands.open_file_or_link("http://light.pinsupreme.com/icon_fonts_themefy.html")
|
66
|
+
else
|
67
|
+
puts "Sorry! We can't open these URLs automatically on your platform, but you can visit them manually:"
|
68
|
+
puts ""
|
69
|
+
puts " http://light.pinsupreme.com/icon_fonts_themefy.html"
|
70
|
+
end
|
65
71
|
puts ""
|
66
72
|
puts "Did you find an icon you wanted to use? Enter the name here or hit enter to just"
|
67
73
|
puts "use the dollar symbol:"
|
@@ -41,6 +41,30 @@ module Scaffolding::BlockManipulator
|
|
41
41
|
lines
|
42
42
|
end
|
43
43
|
|
44
|
+
# This method unwraps the block from the perspective of the child.
|
45
|
+
#
|
46
|
+
# 2.times do
|
47
|
+
# 3.times do
|
48
|
+
# puts "foo"
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# Here we would pass the index of `"3.times do\n"` to
|
53
|
+
# `block_start` which would result in removing the outer block.
|
54
|
+
def self.unwrap_block(lines:, block_start:)
|
55
|
+
block_start = if block_start.is_a? String
|
56
|
+
block_start_line = lines.find { |line| line.match?(block_start) }
|
57
|
+
lines.index(block_start_line)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Find the proper indices for both child and parent blocks.
|
61
|
+
block_parent_start = find_block_parent(block_start, lines)
|
62
|
+
block_parent_end = find_block_end(starting_from: block_parent_start, lines: lines)
|
63
|
+
|
64
|
+
new_lines = shift_block(lines: lines, block_start: block_start)
|
65
|
+
new_lines.reject.with_index { |lines, idx| idx == block_parent_start || idx == block_parent_end }
|
66
|
+
end
|
67
|
+
|
44
68
|
def self.insert(content, lines:, within: nil, after: nil, before: nil, after_block: nil, append: false)
|
45
69
|
# Search for before like we do after, we'll just inject before it.
|
46
70
|
after ||= before
|
@@ -133,7 +157,7 @@ module Scaffolding::BlockManipulator
|
|
133
157
|
# This loop was previously in the RoutesFileManipulator.
|
134
158
|
lines.each_with_index do |line, line_number|
|
135
159
|
next unless line_number > starting_from
|
136
|
-
if /^#{indentation_of(starting_from, lines)}end\s
|
160
|
+
if /^#{indentation_of(starting_from, lines)}end\s*/.match?(line)
|
137
161
|
return line_number
|
138
162
|
end
|
139
163
|
end
|
@@ -159,4 +183,27 @@ module Scaffolding::BlockManipulator
|
|
159
183
|
rescue
|
160
184
|
nil
|
161
185
|
end
|
186
|
+
|
187
|
+
# Shifts the block either to the left or right.
|
188
|
+
def self.shift_block(lines:, block_start:, direction: :left, amount: 2, shift_contents_only: false)
|
189
|
+
block_start = lines.index(block_start) if block_start.is_a? String
|
190
|
+
block_range = (block_start..(find_block_end(starting_from: block_start, lines: lines)))
|
191
|
+
block_range = (block_range.first + 1)..(block_range.last - 1) if shift_contents_only
|
192
|
+
new_lines = []
|
193
|
+
|
194
|
+
lines.each_with_index do |line, line_number|
|
195
|
+
if block_range.cover?(line_number)
|
196
|
+
# If we're shifting a block to the left, we want to safeguard
|
197
|
+
# the String so it doesn't delete any excess characters.
|
198
|
+
if direction == :left
|
199
|
+
amount.times { line = line.gsub(/^\s/, "") }
|
200
|
+
elsif direction == :right
|
201
|
+
line = "\s" * amount + line
|
202
|
+
end
|
203
|
+
end
|
204
|
+
new_lines << line
|
205
|
+
end
|
206
|
+
|
207
|
+
new_lines
|
208
|
+
end
|
162
209
|
end
|
@@ -100,6 +100,11 @@ class Scaffolding::ClassNamesTransformer
|
|
100
100
|
parent.pluralize.titlecase.tr("/", " ")
|
101
101
|
when "Scaffolding Completely Concrete Tangible Things"
|
102
102
|
child.pluralize.titlecase.tr("/", " ")
|
103
|
+
|
104
|
+
# This is a specific example for locales where we only leave tangible_things.
|
105
|
+
when "scaffolding.completely_concrete.tangible_things"
|
106
|
+
child.underscore.pluralize
|
107
|
+
|
103
108
|
when "Scaffolding/Absolutely Abstract/Creative Concepts"
|
104
109
|
parent.pluralize.titlecase
|
105
110
|
when "Scaffolding/Completely Concrete/Tangible Things"
|
@@ -6,9 +6,6 @@ require "scaffolding/class_names_transformer"
|
|
6
6
|
class Scaffolding::Transformer
|
7
7
|
attr_accessor :child, :parent, :parents, :class_names_transformer, :cli_options, :additional_steps, :namespace, :suppress_could_not_find
|
8
8
|
|
9
|
-
def code_for_child_on_parent_show_page
|
10
|
-
end
|
11
|
-
|
12
9
|
def update_models_abstract_class
|
13
10
|
end
|
14
11
|
|
@@ -101,6 +98,7 @@ class Scaffolding::Transformer
|
|
101
98
|
"scaffolding_completely_concrete_tangible_thing",
|
102
99
|
"scaffolding-absolutely-abstract-creative-concept",
|
103
100
|
"scaffolding-completely-concrete-tangible-thing",
|
101
|
+
"scaffolding.completely_concrete.tangible_things",
|
104
102
|
|
105
103
|
# class name in context plural.
|
106
104
|
"absolutely_abstract_creative_concepts",
|
@@ -703,7 +701,7 @@ class Scaffolding::Transformer
|
|
703
701
|
when "file_field"
|
704
702
|
"file"
|
705
703
|
when "password_field"
|
706
|
-
"
|
704
|
+
"text"
|
707
705
|
else
|
708
706
|
raise "Invalid field type: #{type}."
|
709
707
|
end
|
@@ -912,6 +910,10 @@ class Scaffolding::Transformer
|
|
912
910
|
<%= render 'shared/attributes/#{attribute_partial}', attribute: :#{attribute_name} %>
|
913
911
|
ERB
|
914
912
|
|
913
|
+
if type == "password_field"
|
914
|
+
field_content.gsub!(/\s%>/, ", options: { password: true } %>")
|
915
|
+
end
|
916
|
+
|
915
917
|
scaffold_add_line_to_file("./app/views/account/scaffolding/completely_concrete/tangible_things/show.html.erb", field_content.strip, ERB_NEW_FIELDS_HOOK, prepend: true)
|
916
918
|
|
917
919
|
end
|
@@ -940,8 +942,12 @@ class Scaffolding::Transformer
|
|
940
942
|
<td#{cell_attributes}><%= render 'shared/attributes/#{attribute_partial}', attribute: :#{attribute_name}#{", #{table_cell_options.join(", ")}" if table_cell_options.any?} %></td>
|
941
943
|
ERB
|
942
944
|
|
945
|
+
if type == "password_field"
|
946
|
+
field_content.gsub!(/\s%>/, ", options: { password: true } %>")
|
947
|
+
end
|
948
|
+
|
943
949
|
unless ["Team", "User"].include?(child)
|
944
|
-
scaffold_add_line_to_file("./app/views/account/scaffolding/completely_concrete/tangible_things/
|
950
|
+
scaffold_add_line_to_file("./app/views/account/scaffolding/completely_concrete/tangible_things/_tangible_thing.html.erb", field_content.strip, ERB_NEW_FIELDS_HOOK, prepend: true)
|
945
951
|
end
|
946
952
|
|
947
953
|
end
|
@@ -1040,6 +1046,10 @@ class Scaffolding::Transformer
|
|
1040
1046
|
elsif is_multiple
|
1041
1047
|
"assign_checkboxes(strong_params, :#{name})"
|
1042
1048
|
end
|
1049
|
+
when "options"
|
1050
|
+
if is_multiple
|
1051
|
+
"assign_checkboxes(strong_params, :#{name})"
|
1052
|
+
end
|
1043
1053
|
when "super_select"
|
1044
1054
|
if boolean_buttons
|
1045
1055
|
"assign_boolean(strong_params, :#{name})"
|
@@ -1059,7 +1069,9 @@ class Scaffolding::Transformer
|
|
1059
1069
|
|
1060
1070
|
# TODO The serializers can't handle these `has_rich_text` attributes.
|
1061
1071
|
unless type == "trix_editor"
|
1062
|
-
|
1072
|
+
unless type == "file_field"
|
1073
|
+
scaffold_add_line_to_file("./app/views/api/v1/scaffolding/completely_concrete/tangible_things/_tangible_thing.json.jbuilder", ":#{name},", RUBY_NEW_FIELDS_HOOK, prepend: true, suppress_could_not_find: true)
|
1074
|
+
end
|
1063
1075
|
|
1064
1076
|
assertion = case type
|
1065
1077
|
when "date_field"
|
@@ -1067,8 +1079,7 @@ class Scaffolding::Transformer
|
|
1067
1079
|
when "date_and_time_field"
|
1068
1080
|
"assert_equal_or_nil DateTime.parse(tangible_thing_data['#{name}']), tangible_thing.#{name}"
|
1069
1081
|
when "file_field"
|
1070
|
-
#
|
1071
|
-
"# assert tangible_thing_data['#{name}'].match?('foo.txt') unless response.status == 201"
|
1082
|
+
"assert_equal tangible_thing_data['#{name}'], rails_blob_path(@tangible_thing.#{name}) unless controller.action_name == 'create'"
|
1072
1083
|
else
|
1073
1084
|
"assert_equal_or_nil tangible_thing_data['#{name}'], tangible_thing.#{name}"
|
1074
1085
|
end
|
@@ -1077,10 +1088,13 @@ class Scaffolding::Transformer
|
|
1077
1088
|
|
1078
1089
|
# File fields are handled in a specific way when using the jsonapi-serializer.
|
1079
1090
|
if type == "file_field"
|
1080
|
-
|
1091
|
+
scaffold_add_line_to_file("./app/views/api/v1/scaffolding/completely_concrete/tangible_things/_tangible_thing.json.jbuilder", "json.#{name} url_for(tangible_thing.#{name}) if tangible_thing.#{name}.attached?", RUBY_FILES_HOOK, prepend: true, suppress_could_not_find: true)
|
1081
1092
|
# We also want to make sure we attach the dummy file in the API test on setup
|
1082
1093
|
file_name = "./test/controllers/api/v1/scaffolding/completely_concrete/tangible_things_controller_test.rb"
|
1083
|
-
content =
|
1094
|
+
content = <<~RUBY
|
1095
|
+
@#{child.underscore}.#{name} = Rack::Test::UploadedFile.new("test/support/foo.txt")
|
1096
|
+
@another_#{child.underscore}.#{name} = Rack::Test::UploadedFile.new("test/support/foo.txt")
|
1097
|
+
RUBY
|
1084
1098
|
scaffold_add_line_to_file(file_name, content, RUBY_FILES_HOOK, prepend: true)
|
1085
1099
|
end
|
1086
1100
|
|
@@ -1214,6 +1228,25 @@ class Scaffolding::Transformer
|
|
1214
1228
|
end
|
1215
1229
|
end
|
1216
1230
|
|
1231
|
+
# Add `default: false` to boolean migrations.
|
1232
|
+
if boolean_buttons
|
1233
|
+
confirmation_reference = "create_table :#{class_names_transformer.table_name}"
|
1234
|
+
confirmation_migration_file_name = `grep "#{confirmation_reference}" db/migrate/*`.split(":").first
|
1235
|
+
|
1236
|
+
old_line, new_line = nil
|
1237
|
+
File.open(confirmation_migration_file_name) do |migration_file|
|
1238
|
+
old_lines = migration_file.readlines
|
1239
|
+
old_lines.each do |line|
|
1240
|
+
target_attribute = line.match?(/\s*t\.boolean :#{name}/)
|
1241
|
+
if target_attribute
|
1242
|
+
old_line = line
|
1243
|
+
new_line = "#{old_line.chomp}, default: false\n"
|
1244
|
+
end
|
1245
|
+
end
|
1246
|
+
end
|
1247
|
+
replace_in_file(confirmation_migration_file_name, old_line, new_line)
|
1248
|
+
end
|
1249
|
+
|
1217
1250
|
end
|
1218
1251
|
|
1219
1252
|
#
|
@@ -1239,18 +1272,23 @@ class Scaffolding::Transformer
|
|
1239
1272
|
end
|
1240
1273
|
RUBY
|
1241
1274
|
|
1242
|
-
# Generating a model with an `attachment` data type (i.e. - `rails g ModelName file:attachment`)
|
1243
|
-
# adds `has_one_attached` to our model, just not directly above the
|
1244
|
-
# We move the string here so it's
|
1275
|
+
# Generating a model with an `attachment(s)` data type (i.e. - `rails g ModelName file:attachment`)
|
1276
|
+
# adds `has_one_attached` or `has_many_attached` to our model, just not directly above the
|
1277
|
+
# HAS_ONE_HOOK or the HAS_MANY_HOOK. We move the string here so it's scaffolded above the proper hook.
|
1245
1278
|
model_file_path = transform_string("./app/models/scaffolding/completely_concrete/tangible_thing.rb")
|
1246
1279
|
model_contents = File.readlines(model_file_path)
|
1247
|
-
|
1280
|
+
reflection_declaration = is_multiple ? "has_many_attached :#{name}" : "has_one_attached :#{name}"
|
1281
|
+
|
1282
|
+
# Save the file without the hook so we can write it via the `scaffold_add_line_to_file` method below.
|
1283
|
+
model_without_attached_hook = model_contents.reject.each { |line| line.include?(reflection_declaration) }
|
1248
1284
|
File.open(model_file_path, "w") do |f|
|
1249
1285
|
model_without_attached_hook.each { |line| f.write(line) }
|
1250
1286
|
end
|
1251
1287
|
|
1252
|
-
|
1288
|
+
hook_type = is_multiple ? HAS_MANY_HOOK : HAS_ONE_HOOK
|
1289
|
+
scaffold_add_line_to_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", reflection_declaration, hook_type, prepend: true)
|
1253
1290
|
|
1291
|
+
# TODO: We may need to edit these depending on how we save multiple files.
|
1254
1292
|
scaffold_add_line_to_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", "attr_accessor :#{name}_removal", ATTR_ACCESSORS_HOOK, prepend: true)
|
1255
1293
|
scaffold_add_line_to_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", remove_file_methods, METHODS_HOOK, prepend: true)
|
1256
1294
|
scaffold_add_line_to_file("./app/models/scaffolding/completely_concrete/tangible_thing.rb", "after_validation :remove_#{name}, if: :#{name}_removal?", CALLBACKS_HOOK, prepend: true)
|
@@ -1295,7 +1333,8 @@ class Scaffolding::Transformer
|
|
1295
1333
|
files = if cli_options["only-index"]
|
1296
1334
|
[
|
1297
1335
|
"./app/views/account/scaffolding/completely_concrete/tangible_things/_index.html.erb",
|
1298
|
-
"./app/views/account/scaffolding/completely_concrete/tangible_things/index.html.erb"
|
1336
|
+
"./app/views/account/scaffolding/completely_concrete/tangible_things/index.html.erb",
|
1337
|
+
"./app/views/account/scaffolding/completely_concrete/tangible_things/_tangible_thing.html.erb"
|
1299
1338
|
]
|
1300
1339
|
else
|
1301
1340
|
# copy a ton of files over and do the appropriate string replace.
|
@@ -1362,7 +1401,7 @@ class Scaffolding::Transformer
|
|
1362
1401
|
unless cli_options["skip-parent"] || parent == "None"
|
1363
1402
|
scaffold_add_line_to_file(
|
1364
1403
|
"./app/views/account/scaffolding/absolutely_abstract/creative_concepts/show.html.erb",
|
1365
|
-
|
1404
|
+
"<%= render 'account/scaffolding/completely_concrete/tangible_things/index', tangible_things: @creative_concept.completely_concrete_tangible_things, hide_back: true %>",
|
1366
1405
|
"<%# 🚅 super scaffolding will insert new children above this line. %>",
|
1367
1406
|
prepend: true
|
1368
1407
|
)
|
@@ -1501,7 +1540,7 @@ class Scaffolding::Transformer
|
|
1501
1540
|
puts "enter the name of the icon you want to use."
|
1502
1541
|
puts "(Or hit enter when choosing to skip this step.)"
|
1503
1542
|
$stdin.gets.chomp
|
1504
|
-
if
|
1543
|
+
if TerminalCommands.can_open?
|
1505
1544
|
TerminalCommands.open_file_or_link("https://themify.me/themify-icons")
|
1506
1545
|
if font_awesome?
|
1507
1546
|
TerminalCommands.open_file_or_link("https://fontawesome.com/icons?d=gallery&s=light")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bullet_train-super_scaffolding
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Culver
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: standard
|
@@ -100,6 +100,7 @@ files:
|
|
100
100
|
- app/models/scaffolding/completely_concrete/tangible_things.rb
|
101
101
|
- app/models/scaffolding/completely_concrete/tangible_things/assignment.rb
|
102
102
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/_breadcrumbs.html.erb
|
103
|
+
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/_creative_concept.html.erb
|
103
104
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/_creative_concept.json.jbuilder
|
104
105
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/_form.html.erb
|
105
106
|
- app/views/account/scaffolding/absolutely_abstract/creative_concepts/_index.html.erb
|
@@ -125,6 +126,7 @@ files:
|
|
125
126
|
- app/views/account/scaffolding/completely_concrete/tangible_things/_form.html.erb
|
126
127
|
- app/views/account/scaffolding/completely_concrete/tangible_things/_index.html.erb
|
127
128
|
- app/views/account/scaffolding/completely_concrete/tangible_things/_menu_item.html.erb
|
129
|
+
- app/views/account/scaffolding/completely_concrete/tangible_things/_tangible_thing.html.erb
|
128
130
|
- app/views/account/scaffolding/completely_concrete/tangible_things/edit.html.erb
|
129
131
|
- app/views/account/scaffolding/completely_concrete/tangible_things/index.html.erb
|
130
132
|
- app/views/account/scaffolding/completely_concrete/tangible_things/new.html.erb
|