dynamic_scaffold 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/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
@@ -0,0 +1,115 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
module ControllerUtilities
|
3
|
+
private
|
4
|
+
|
5
|
+
# Get the hash of the key and value specified for the scope.
|
6
|
+
def scope_params
|
7
|
+
return {} if dynamic_scaffold.scope.nil?
|
8
|
+
dynamic_scaffold.scope.each_with_object({}) {|attr, res| res[attr] = params[attr] }
|
9
|
+
end
|
10
|
+
|
11
|
+
# Get the primary key hash from the update parameters.
|
12
|
+
def extract_pkeys(values)
|
13
|
+
[*dynamic_scaffold.model.primary_key].each_with_object({}) {|col, res| res[col] = values[col] }
|
14
|
+
end
|
15
|
+
|
16
|
+
# Convert pkey_string value to hash.
|
17
|
+
def pkey_string_to_hash(pkey)
|
18
|
+
# https://github.com/gomo/dynamic_scaffold/pull/9/commits/ff5de0e38b3544347e82539c45ffd2efaf3410da
|
19
|
+
# Stop support multiple pkey, on this commit.
|
20
|
+
# Convert "key:1,code:foo" to {key: "1", code: "foo"}
|
21
|
+
pkey.split(',').map {|v| v.split(':') }.each_with_object({}) {|v, res| res[v.first] = v.last }
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get parameters for edit action. `key[column] => value`
|
25
|
+
def edit_params
|
26
|
+
params.permit(*dynamic_scaffold.model.primary_key)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Get paramters for sort action. `pkeys[][column] => value`
|
30
|
+
def sort_params
|
31
|
+
params
|
32
|
+
.require('pkeys')
|
33
|
+
.map {|p| p.permit(*dynamic_scaffold.model.primary_key) }
|
34
|
+
end
|
35
|
+
|
36
|
+
# Get paramters for update record.
|
37
|
+
def update_values
|
38
|
+
values = params
|
39
|
+
.require(dynamic_scaffold.model.name.underscore)
|
40
|
+
.permit(*dynamic_scaffold.form.items.map(&:strong_parameter))
|
41
|
+
|
42
|
+
if dynamic_scaffold.scope && !valid_for_scope?(values)
|
43
|
+
raise DynamicScaffold::Error::Controller, "You can update only to #{scope_params} on this scope"
|
44
|
+
end
|
45
|
+
|
46
|
+
values
|
47
|
+
end
|
48
|
+
|
49
|
+
# Check if there are inconsistent scopes in update parameters
|
50
|
+
def valid_for_scope?(update_params)
|
51
|
+
result = true
|
52
|
+
scope_params.each do |key, value|
|
53
|
+
if update_params.key?(key) && update_params[key] != value
|
54
|
+
result = false
|
55
|
+
break
|
56
|
+
end
|
57
|
+
end
|
58
|
+
result
|
59
|
+
end
|
60
|
+
|
61
|
+
def reset_sequence(record_count)
|
62
|
+
if dynamic_scaffold.list.sorter_direction == :asc
|
63
|
+
@sequence = 0
|
64
|
+
elsif dynamic_scaffold.list.sorter_direction == :desc
|
65
|
+
@sequence = record_count - 1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def next_sequence!
|
70
|
+
val = @sequence
|
71
|
+
if dynamic_scaffold.list.sorter_direction == :asc
|
72
|
+
@sequence += 1
|
73
|
+
elsif dynamic_scaffold.list.sorter_direction == :desc
|
74
|
+
@sequence -= 1
|
75
|
+
end
|
76
|
+
val
|
77
|
+
end
|
78
|
+
|
79
|
+
def find_record(params)
|
80
|
+
rec = dynamic_scaffold.model.find_by(params.merge(scope_params))
|
81
|
+
raise ::ActiveRecord::RecordNotFound if rec.nil?
|
82
|
+
rec
|
83
|
+
end
|
84
|
+
|
85
|
+
def dynamic_scaffold_path(action, options = {})
|
86
|
+
route = Rails.application.routes.routes.find do |r|
|
87
|
+
route_params = r.required_defaults
|
88
|
+
route_params[:controller] == params[:controller] && (route_params[:action] == action.to_s && r.name)
|
89
|
+
end
|
90
|
+
|
91
|
+
if route.nil?
|
92
|
+
raise DynamicScaffold::Error::RouteNotFound,
|
93
|
+
"Missing controller#action #{params[:controller]}##{action}"
|
94
|
+
end
|
95
|
+
|
96
|
+
options.merge!(scope_params)
|
97
|
+
|
98
|
+
public_send("#{route.name}_path", options)
|
99
|
+
end
|
100
|
+
|
101
|
+
def dynamic_scaffold_icon(name)
|
102
|
+
view_context.instance_exec name, &::Rails.application.config.dynamic_scaffold.icons
|
103
|
+
end
|
104
|
+
|
105
|
+
def primary_key_value(record)
|
106
|
+
[*record.class.primary_key].each_with_object({}) {|col, res| res[col] = record[col] }
|
107
|
+
end
|
108
|
+
|
109
|
+
def bind_sorter_value(record)
|
110
|
+
attr = dynamic_scaffold.list.sorter_attribute
|
111
|
+
value = dynamic_scaffold.model.maximum(attr)
|
112
|
+
record[attr] = value ? value + 1 : 0
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'classnames-rails-view'
|
2
|
+
module DynamicScaffold
|
3
|
+
class Engine < ::Rails::Engine
|
4
|
+
config.dynamic_scaffold = ActiveSupport::OrderedOptions.new
|
5
|
+
config.dynamic_scaffold.icon_set = :fontawesome
|
6
|
+
|
7
|
+
config.autoload_paths += Dir["#{config.root}/lib/**/"]
|
8
|
+
config.assets.precompile += %w[dynamic_scaffold/*]
|
9
|
+
|
10
|
+
require 'dynamic_scaffold/routes'
|
11
|
+
|
12
|
+
config.after_initialize do |_app|
|
13
|
+
if Rails.application.config.dynamic_scaffold.icons.nil?
|
14
|
+
require "dynamic_scaffold/icons/#{config.dynamic_scaffold.icon_set}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
module Form
|
3
|
+
module Item
|
4
|
+
class Base
|
5
|
+
attr_reader :name
|
6
|
+
def initialize(config, type, name, html_attributes = {})
|
7
|
+
@config = config
|
8
|
+
@name = name
|
9
|
+
@type = type
|
10
|
+
@html_attributes = html_attributes
|
11
|
+
classnames = @html_attributes.delete(:class)
|
12
|
+
@classnames_list = []
|
13
|
+
@classnames_list.push(classnames) if classnames
|
14
|
+
@notes = []
|
15
|
+
@multiple = type == :collection_check_boxes || html_attributes[:multiple]
|
16
|
+
end
|
17
|
+
|
18
|
+
def notes?
|
19
|
+
!@notes.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
def note(&block)
|
23
|
+
@notes << block if block_given?
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def render_notes(record, view)
|
28
|
+
htmls = @notes.map do |note|
|
29
|
+
view.instance_exec(record, ¬e)
|
30
|
+
end
|
31
|
+
view.safe_join(htmls)
|
32
|
+
end
|
33
|
+
|
34
|
+
def type?(type)
|
35
|
+
@type == type
|
36
|
+
end
|
37
|
+
|
38
|
+
def label?
|
39
|
+
!@label.nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
def label(label = nil, &block)
|
43
|
+
if block_given?
|
44
|
+
raise Error::InvalidParameter, 'Only the block type accepts block.' unless type? :block
|
45
|
+
@block = block
|
46
|
+
end
|
47
|
+
if label
|
48
|
+
@label = label
|
49
|
+
self
|
50
|
+
else
|
51
|
+
return @label if @label
|
52
|
+
@config.model.human_attribute_name @name
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def strong_parameter
|
57
|
+
return { @name => [] } if @multiple
|
58
|
+
@name
|
59
|
+
end
|
60
|
+
|
61
|
+
def if(&block)
|
62
|
+
@if_block = block
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
def unless(&block)
|
67
|
+
@unless_block = block
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
def needs_rendering?(view)
|
72
|
+
return true unless @if_block || @unless_block
|
73
|
+
return view.instance_exec(view.controller.params, &@if_block) if @if_block
|
74
|
+
return !view.instance_exec(view.controller.params, &@unless_block) if @unless_block
|
75
|
+
end
|
76
|
+
|
77
|
+
def proxy(attribute_name)
|
78
|
+
@proxy = attribute_name
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
def proxy_field
|
83
|
+
return self unless @proxy
|
84
|
+
proxy_target = @config.form.items.select {|f| f.name == @proxy }
|
85
|
+
raise DynamicScaffold::Error::InvalidParameter, "Missing proxy target element: #{@proxy}" if proxy_target.empty?
|
86
|
+
proxy_target.first
|
87
|
+
end
|
88
|
+
|
89
|
+
def default(value = nil)
|
90
|
+
return @default if value.nil?
|
91
|
+
@default = value
|
92
|
+
end
|
93
|
+
|
94
|
+
protected
|
95
|
+
|
96
|
+
def build_html_attributes(classnames)
|
97
|
+
classnames_list = @classnames_list
|
98
|
+
classnames_list = [*classnames_list, classnames] if classnames
|
99
|
+
options = @html_attributes.dup
|
100
|
+
options[:class] = classnames_list.join(' ') unless classnames_list.empty?
|
101
|
+
options
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
module Form
|
3
|
+
module Item
|
4
|
+
class Block < Base
|
5
|
+
def initialize(config, type, name, block)
|
6
|
+
super(config, type, name, {})
|
7
|
+
@block = block
|
8
|
+
end
|
9
|
+
|
10
|
+
def render(view, form, classnames = nil)
|
11
|
+
view.instance_exec(form, self, classnames, &@block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
module Form
|
3
|
+
module Item
|
4
|
+
class SingleOption < Base
|
5
|
+
def initialize(config, type, *args)
|
6
|
+
name = args.shift
|
7
|
+
html_attributes = args.extract_options!
|
8
|
+
@args = args
|
9
|
+
super(config, type, name, html_attributes)
|
10
|
+
end
|
11
|
+
|
12
|
+
def render(_view, form, classnames = nil)
|
13
|
+
html_attributes = build_html_attributes(classnames)
|
14
|
+
# Retain the value of the password field on error.
|
15
|
+
html_attributes[:value] = form.object.public_send(@name) if @type == :password_field
|
16
|
+
form.public_send(@type, @name, *@args, html_attributes)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
module Form
|
3
|
+
module Item
|
4
|
+
class TwoOptions < Base
|
5
|
+
def initialize(config, type, *args)
|
6
|
+
name = args.shift
|
7
|
+
# rubocop:disable Style/IdenticalConditionalBranches
|
8
|
+
if args[args.length - 2].is_a?(Hash)
|
9
|
+
html_attributes = args.extract_options!
|
10
|
+
@options = args.extract_options!
|
11
|
+
else
|
12
|
+
html_attributes = {}
|
13
|
+
@options = args.extract_options!
|
14
|
+
end
|
15
|
+
# rubocop:enable Style/IdenticalConditionalBranches
|
16
|
+
|
17
|
+
@args = args
|
18
|
+
super(config, type, name, html_attributes)
|
19
|
+
end
|
20
|
+
|
21
|
+
def render(_view, form, classnames = nil)
|
22
|
+
html_attributes = build_html_attributes(classnames)
|
23
|
+
form.public_send(@type, @name, *@args, @options, html_attributes)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
module Form
|
3
|
+
module Item
|
4
|
+
class TwoOptionsWithBlock < TwoOptions
|
5
|
+
def render(_view, form, classnames = nil)
|
6
|
+
form.public_send(
|
7
|
+
@type,
|
8
|
+
@name,
|
9
|
+
*@args,
|
10
|
+
@options,
|
11
|
+
build_html_attributes(classnames)
|
12
|
+
) do |builder|
|
13
|
+
yield builder
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
module Fontawesome
|
3
|
+
def self.inline_svg(path)
|
4
|
+
Rails.cache.fetch "dynamic_scaffold/fontawesome/icons/#{path}" do
|
5
|
+
full_path = DynamicScaffold::Engine.root.join('app', 'assets', 'images', 'dynamic_scaffold', 'fontawesome', path)
|
6
|
+
file = File.open(full_path)
|
7
|
+
file.read.gsub!('<svg ', '<svg class="dynamicScaffold-svg-icon" ').html_safe # rubocop:disable Rails/OutputSafety, Metrics/LineLength
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
Rails.application.config.dynamic_scaffold.icons = proc do |name|
|
13
|
+
# This function is called in view scope.
|
14
|
+
# https://github.com/gomo/dynamic_scaffold/blob/b4066bbd40cd6e7307ce283d5a9bd526ae124e00/lib/dynamic_scaffold/controller_utilities.rb#L104-L106
|
15
|
+
case name
|
16
|
+
when :up then
|
17
|
+
DynamicScaffold::Fontawesome.inline_svg('chevron-up.svg')
|
18
|
+
when :down then
|
19
|
+
DynamicScaffold::Fontawesome.inline_svg('chevron-down.svg')
|
20
|
+
when :delete then
|
21
|
+
DynamicScaffold::Fontawesome.inline_svg('times.svg')
|
22
|
+
when :edit then
|
23
|
+
DynamicScaffold::Fontawesome.inline_svg('pencil-alt.svg')
|
24
|
+
when :add then
|
25
|
+
DynamicScaffold::Fontawesome.inline_svg('plus.svg')
|
26
|
+
when :save then
|
27
|
+
DynamicScaffold::Fontawesome.inline_svg('hdd.svg')
|
28
|
+
when :back then
|
29
|
+
DynamicScaffold::Fontawesome.inline_svg('chevron-left.svg')
|
30
|
+
when :error then
|
31
|
+
DynamicScaffold::Fontawesome.inline_svg('exclamation-circle.svg')
|
32
|
+
when :first then
|
33
|
+
DynamicScaffold::Fontawesome.inline_svg('step-backward.svg')
|
34
|
+
when :last then
|
35
|
+
DynamicScaffold::Fontawesome.inline_svg('step-forward.svg')
|
36
|
+
when :next then
|
37
|
+
DynamicScaffold::Fontawesome.inline_svg('chevron-right.svg')
|
38
|
+
when :prev then
|
39
|
+
DynamicScaffold::Fontawesome.inline_svg('chevron-left.svg')
|
40
|
+
when :top then
|
41
|
+
DynamicScaffold::Fontawesome.inline_svg('angle-double-up.svg')
|
42
|
+
when :bottom then
|
43
|
+
DynamicScaffold::Fontawesome.inline_svg('angle-double-down.svg')
|
44
|
+
else
|
45
|
+
raise DynamicScaffold::Error::InvalidIcon, "Unknown icon type #{name} specified."
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
module List
|
3
|
+
class Item
|
4
|
+
attr_reader :classnames, :html_attributes
|
5
|
+
|
6
|
+
def initialize(config, *args, block)
|
7
|
+
@config = config
|
8
|
+
@html_attributes = args.extract_options!
|
9
|
+
@classnames = @html_attributes.delete(:class)
|
10
|
+
@attribute_name = args[0]
|
11
|
+
@block = block
|
12
|
+
end
|
13
|
+
|
14
|
+
def value(view, record)
|
15
|
+
if @block
|
16
|
+
view.instance_exec(record, @attribute_name, &@block)
|
17
|
+
else
|
18
|
+
record.public_send(@attribute_name)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def label(label = nil, &block)
|
23
|
+
@block = block if block
|
24
|
+
if label
|
25
|
+
@label = label
|
26
|
+
self
|
27
|
+
elsif @label
|
28
|
+
@label
|
29
|
+
elsif @attribute_name
|
30
|
+
@config.model.human_attribute_name @attribute_name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DynamicScaffold
|
2
|
+
module Routes
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
include DynamicScaffold::Routes::LocalInstanceMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module LocalInstanceMethods
|
10
|
+
def dynamic_scaffold_for(*resources)
|
11
|
+
options = resources.extract_options!.dup
|
12
|
+
path = resources[0]
|
13
|
+
resources path, options.merge(except: %i[show]) do
|
14
|
+
collection do
|
15
|
+
patch :sort, controller: options[:controller]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
::ActionDispatch::Routing::Mapper.send :include, DynamicScaffold::Routes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'dynamic_scaffold/version'
|
2
|
+
require 'dynamic_scaffold/engine'
|
3
|
+
require 'dynamic_scaffold/controller_utilities'
|
4
|
+
require 'dynamic_scaffold/controller'
|
5
|
+
require 'dynamic_scaffold/config'
|
6
|
+
|
7
|
+
require 'dynamic_scaffold/error/base'
|
8
|
+
require 'dynamic_scaffold/error/invalid_icon'
|
9
|
+
require 'dynamic_scaffold/error/controller'
|
10
|
+
|
11
|
+
module DynamicScaffold
|
12
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Description:
|
2
|
+
Generate DynamicScaffold's controller and views by specifying a path.
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails generate dynamic_scaffold shops
|
6
|
+
|
7
|
+
This will create for Shop model:
|
8
|
+
app/controllers/shops_controller.rb
|
9
|
+
app/views/shops/edit.html.erb
|
10
|
+
app/views/shops/index.html.erb
|
11
|
+
app/views/shops/new.html.erb
|
12
|
+
|
13
|
+
rails generate dynamic_scaffold controls/county Country
|
14
|
+
|
15
|
+
This will create for Country model:
|
16
|
+
app/controllers/country_controller.rb
|
17
|
+
app/views/country/edit.html.erb
|
18
|
+
app/views/country/index.html.erb
|
19
|
+
app/views/country/new.html.erb
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class DynamicScaffoldGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path('../templates', __FILE__)
|
3
|
+
|
4
|
+
argument :path, type: 'string', required: true
|
5
|
+
argument :model, type: 'string', required: false
|
6
|
+
|
7
|
+
def init
|
8
|
+
@namespases = path.split('/')
|
9
|
+
@plural_model_name = @namespases.pop.camelize
|
10
|
+
@class_scope = @namespases.map(&:camelize).join('::')
|
11
|
+
@model_name = model ? model : @plural_model_name.singularize
|
12
|
+
@model_name = @model_name.camelize
|
13
|
+
@model = @model_name.constantize
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_controllers
|
17
|
+
template 'controller.erb', "app/controllers/#{path}_controller.rb"
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_views
|
21
|
+
%i[edit index new].each do |file|
|
22
|
+
template "views/#{file}.erb", "app/views/#{path}/#{file}.html.erb"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
class <%= @class_scope.present? ? "#{@class_scope}::" : '' %><%= @plural_model_name %>Controller < ApplicationController
|
2
|
+
include DynamicScaffold::Controller
|
3
|
+
dynamic_scaffold <%= @model_name %> do |config|
|
4
|
+
# If you want to use all views common variables, please call `vars`.
|
5
|
+
# Please see https://github.com/gomo/dynamic_scaffold#view-helper for details.
|
6
|
+
# In your view:
|
7
|
+
# <%%= dynamic_scaffold.vars.scope_target.name %>
|
8
|
+
# here:
|
9
|
+
# config.vars :scope_target do
|
10
|
+
# SomeRecord.find(params['some_record_id'])
|
11
|
+
# end
|
12
|
+
|
13
|
+
# You can get the current page title like `Country List`, `Edit Country` in your view.
|
14
|
+
# <%%= dynamic_scaffold.title.current.full %>
|
15
|
+
# If you want change from the model name, set config.title.name.
|
16
|
+
# Please see https://github.com/gomo/dynamic_scaffold#view-helper for details.
|
17
|
+
# config.title.name = 'Model'
|
18
|
+
|
19
|
+
# When you want a simple sort on the column of record, please call order.
|
20
|
+
# config.list.order created_at: :desc
|
21
|
+
|
22
|
+
# To enable sorting, call sorter method specifying the column name and direction.
|
23
|
+
# config.list.sorter sequence: :desc
|
24
|
+
|
25
|
+
# To enable pagination, call pagination. All args is not require, defauls is below
|
26
|
+
# config.list.pagination(
|
27
|
+
# per_page: 25,
|
28
|
+
# window: 0, # kaminari options
|
29
|
+
# outer_window: 0, # kaminari options
|
30
|
+
# left: 0, # kaminari options
|
31
|
+
# right: 0, # kaminari options
|
32
|
+
# param_name: :page, # kaminari options
|
33
|
+
# total_count: true, # Whether to display total count on active page like `2 / 102`
|
34
|
+
# end_buttons: true, # Whether to display buttons to the first and last page.
|
35
|
+
# neighbor_buttons: true, # Whether to display buttons to the next and prev page.
|
36
|
+
# gap_buttons: false, # Whether to display gap buttons.
|
37
|
+
# highlight_current: false, # Whether to highlight the current page.
|
38
|
+
# )
|
39
|
+
|
40
|
+
# To enable scoping, call scope with parameter names you want.
|
41
|
+
# Please see https://github.com/gomo/dynamic_scaffold#scoping for details.
|
42
|
+
# config.scope([role])
|
43
|
+
|
44
|
+
# You can change the items displayed in the list through the `config.list.item`.
|
45
|
+
# Please see https://github.com/gomo/dynamic_scaffold#customize-list for details.
|
46
|
+
|
47
|
+
# You can set each title in the list through title method.
|
48
|
+
# Pass the attribute name,
|
49
|
+
# config.list.title(:name)
|
50
|
+
# or
|
51
|
+
# config.list.title do |record|
|
52
|
+
# record.name
|
53
|
+
# end
|
54
|
+
|
55
|
+
<%- @model.column_names.each do |column| -%>
|
56
|
+
config.list.item(:<%= column %>, style: 'width: 120px;')
|
57
|
+
<%- end -%>
|
58
|
+
|
59
|
+
# You can customize the form fields through `config.form`.
|
60
|
+
# Please see https://github.com/gomo/dynamic_scaffold#customize-form for details.
|
61
|
+
<%- @model.column_names.each do |column| -%>
|
62
|
+
config.form.item(:text_field, :<%= column %>)
|
63
|
+
<%- end -%>
|
64
|
+
end
|
65
|
+
|
66
|
+
# def index
|
67
|
+
# super do |query|
|
68
|
+
# # If you want append database queries, Write here.
|
69
|
+
# # Do not forget to return query.
|
70
|
+
# end
|
71
|
+
# end
|
72
|
+
|
73
|
+
# def new
|
74
|
+
# super
|
75
|
+
# end
|
76
|
+
|
77
|
+
# def edit
|
78
|
+
# super
|
79
|
+
# end
|
80
|
+
|
81
|
+
# def create
|
82
|
+
# super do |record, prev_attribute|
|
83
|
+
# # If you want to modify the attributes of the record before saving, Write here.
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
|
87
|
+
# def update
|
88
|
+
# super do |record, prev_attribute|
|
89
|
+
# # If you want to modify the attributes of the record before saving, Write here.
|
90
|
+
# end
|
91
|
+
# end
|
92
|
+
|
93
|
+
# def destroy
|
94
|
+
# super
|
95
|
+
# end
|
96
|
+
|
97
|
+
# def sort
|
98
|
+
# super
|
99
|
+
# end
|
100
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%%= render 'dynamic_scaffold/bootstrap/edit' %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%%= render 'dynamic_scaffold/bootstrap/list' %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%%= render 'dynamic_scaffold/bootstrap/new' %>
|