active_scaffold 3.6.0.rc1 → 3.6.2
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 +4 -4
- data/CHANGELOG.rdoc +26 -0
- data/README.md +10 -9
- data/app/assets/javascripts/jquery/active_scaffold.js +48 -14
- data/app/assets/stylesheets/active_scaffold_layout.css +1 -1
- data/app/views/active_scaffold_overrides/_form_association.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +22 -6
- data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +3 -3
- data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_vertical_subform.html.erb +2 -2
- data/app/views/active_scaffold_overrides/update_column.js.erb +1 -1
- data/lib/active_scaffold/actions/core.rb +5 -2
- data/lib/active_scaffold/actions/list.rb +1 -1
- data/lib/active_scaffold/actions/nested.rb +1 -1
- data/lib/active_scaffold/actions/subform.rb +12 -6
- data/lib/active_scaffold/attribute_params.rb +6 -16
- data/lib/active_scaffold/bridges/active_storage/active_storage_bridge.rb +1 -0
- data/lib/active_scaffold/bridges/active_storage/list_ui.rb +4 -4
- data/lib/active_scaffold/bridges/bitfields.rb +1 -1
- data/lib/active_scaffold/bridges/bitfields/list_ui.rb +19 -0
- data/lib/active_scaffold/bridges/paper_trail/actions.rb +3 -1
- data/lib/active_scaffold/bridges/record_select/helpers.rb +3 -1
- data/lib/active_scaffold/config/list.rb +1 -1
- data/lib/active_scaffold/data_structures/action_columns.rb +1 -1
- data/lib/active_scaffold/data_structures/association/abstract.rb +1 -4
- data/lib/active_scaffold/data_structures/nested_info.rb +14 -2
- data/lib/active_scaffold/extensions/action_view_rendering.rb +66 -25
- data/lib/active_scaffold/extensions/localize.rb +1 -1
- data/lib/active_scaffold/finder.rb +7 -5
- data/lib/active_scaffold/helpers/controller_helpers.rb +11 -0
- data/lib/active_scaffold/helpers/form_column_helpers.rb +52 -15
- data/lib/active_scaffold/helpers/list_column_helpers.rb +10 -6
- data/lib/active_scaffold/helpers/search_column_helpers.rb +14 -7
- data/lib/active_scaffold/helpers/view_helpers.rb +1 -1
- data/lib/active_scaffold/tableless.rb +16 -2
- data/lib/active_scaffold/version.rb +1 -1
- data/lib/generators/active_scaffold/install_generator.rb +51 -3
- data/test/data_structures/action_columns_test.rb +1 -1
- data/test/extensions/action_view_rendering_test.rb +20 -0
- data/test/misc/constraints_test.rb +1 -1
- data/test/misc/tableless_test.rb +8 -0
- data/test/mock_app/app/controllers/people_controller.rb +2 -0
- data/test/mock_app/app/controllers/roles_controller.rb +4 -0
- data/test/mock_app/app/views/active_scaffold_overrides/_form.html.erb +2 -0
- data/test/mock_app/app/views/active_scaffold_overrides/list.html.erb +2 -0
- data/test/mock_app/app/views/people/_first_name_form_column.html.erb +2 -0
- data/test/mock_app/app/views/people/_form.html.erb +2 -0
- data/test/mock_app/app/views/people/list.html.erb +2 -0
- data/test/test_helper.rb +2 -2
- metadata +25 -4
@@ -1,6 +1,6 @@
|
|
1
1
|
class ActiveScaffold::Bridges::Bitfields < ActiveScaffold::DataStructures::Bridge
|
2
2
|
def self.install
|
3
|
-
|
3
|
+
Dir[File.join(__dir__, 'bitfields', '*.rb')].each { |file| require file }
|
4
4
|
ActiveScaffold::Config::Core.send :prepend, ActiveScaffold::Bridges::Bitfields::BitfieldsBridge
|
5
5
|
ActiveScaffold::Config::Core.after_config_callbacks << :_setup_bitfields
|
6
6
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveScaffold
|
2
|
+
module Bridges
|
3
|
+
class Bitfields
|
4
|
+
module ListColumnHelpers
|
5
|
+
def format_column_value(record, column, value = nil)
|
6
|
+
if record.class.respond_to?(:bitfields) && record.class.bitfields&.include?(column.name)
|
7
|
+
value = record.bitfield_values(column.name).select { |_, v| v }.keys
|
8
|
+
safe_join active_scaffold_config.columns.select { |c| c.name.in? value }.map(&:label), ', '
|
9
|
+
else
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
ActionView::Base.class_eval do
|
18
|
+
include ActiveScaffold::Bridges::Bitfields::ListColumnHelpers
|
19
|
+
end
|
@@ -11,7 +11,9 @@ module ActiveScaffold::Actions
|
|
11
11
|
|
12
12
|
def deleted
|
13
13
|
query = PaperTrail::Version.destroys.where(:item_type => active_scaffold_config.model)
|
14
|
-
|
14
|
+
if nested? && nested.child_association&.belongs_to? && PaperTrail::Version.respond_to?(:where_object)
|
15
|
+
query = query.where_object(nested.child_association.foreign_key => nested.parent_id)
|
16
|
+
end
|
15
17
|
pager = Paginator.new(query.count, active_scaffold_config.list.per_page) do |offset, per_page|
|
16
18
|
query.offset(offset).limit(per_page).map(&:reify)
|
17
19
|
end
|
@@ -14,7 +14,9 @@ class ActiveScaffold::Bridges::RecordSelect
|
|
14
14
|
record = options.delete(:object)
|
15
15
|
if column.association&.singular?
|
16
16
|
multiple = column.options.dig(:html_options, :multiple)
|
17
|
-
active_scaffold_record_select(record, column, options, record.send(column.name), multiple)
|
17
|
+
html = active_scaffold_record_select(record, column, options, record.send(column.name), multiple)
|
18
|
+
html << active_scaffold_new_record_subform(column, record, options) if column.options[:add_new]
|
19
|
+
html
|
18
20
|
elsif column.association&.collection?
|
19
21
|
active_scaffold_record_select(record, column, options, record.send(column.name), true)
|
20
22
|
else
|
@@ -292,7 +292,7 @@ module ActiveScaffold::Config
|
|
292
292
|
@_sorting = sorting
|
293
293
|
else
|
294
294
|
@_sorting = default_sorting
|
295
|
-
@_sorting.set(
|
295
|
+
@_sorting.set(*@sorting) if @sorting
|
296
296
|
if @conf.columns.constraint_columns.present?
|
297
297
|
@_sorting.constraint_columns = @conf.columns.constraint_columns
|
298
298
|
end
|
@@ -12,13 +12,10 @@ module ActiveScaffold::DataStructures::Association
|
|
12
12
|
|
13
13
|
def klass(record = nil)
|
14
14
|
if polymorphic?
|
15
|
-
record&.send(foreign_type)&.
|
15
|
+
record&.send(foreign_type)&.safe_constantize
|
16
16
|
else
|
17
17
|
@association.klass
|
18
18
|
end
|
19
|
-
rescue NameError => e
|
20
|
-
Rails.logger.warn "#{e.message}\n#{e.backtrace.join("\n")}"
|
21
|
-
nil
|
22
19
|
end
|
23
20
|
|
24
21
|
def belongs_to?
|
@@ -66,6 +66,10 @@ module ActiveScaffold::DataStructures
|
|
66
66
|
def sorted?(*)
|
67
67
|
false
|
68
68
|
end
|
69
|
+
|
70
|
+
def match_model?(model)
|
71
|
+
false
|
72
|
+
end
|
69
73
|
end
|
70
74
|
|
71
75
|
class NestedInfoAssociation < NestedInfo
|
@@ -100,6 +104,14 @@ module ActiveScaffold::DataStructures
|
|
100
104
|
association.through?
|
101
105
|
end
|
102
106
|
|
107
|
+
def match_model?(model)
|
108
|
+
if association.polymorphic?
|
109
|
+
child_association&.inverse_klass == model
|
110
|
+
else
|
111
|
+
association.klass == model
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
103
115
|
def sorted?(chain)
|
104
116
|
default_sorting(chain).present?
|
105
117
|
end
|
@@ -119,8 +131,8 @@ module ActiveScaffold::DataStructures
|
|
119
131
|
protected
|
120
132
|
|
121
133
|
def setup_constrained_fields
|
122
|
-
@constrained_fields =
|
123
|
-
@constrained_fields ||=
|
134
|
+
@constrained_fields = [] if association.belongs_to? || association.through?
|
135
|
+
@constrained_fields ||= Array(association.foreign_key).map(&:to_sym)
|
124
136
|
return unless child_association && child_association != association
|
125
137
|
|
126
138
|
@constrained_fields << child_association.name
|
@@ -45,31 +45,7 @@ module ActiveScaffold #:nodoc:
|
|
45
45
|
@_view_paths ||= lookup_context.view_paths.clone
|
46
46
|
@_last_template ||= lookup_context.last_template
|
47
47
|
end
|
48
|
-
|
49
|
-
template = parts.pop
|
50
|
-
prefix = parts.join('/')
|
51
|
-
|
52
|
-
options = args[1] || {}
|
53
|
-
options[:locals] ||= {}
|
54
|
-
if view_stack.last
|
55
|
-
options[:locals] = view_stack.last[:locals].merge!(options[:locals]) if view_stack.last[:locals]
|
56
|
-
options[:object] ||= view_stack.last[:object] if view_stack.last[:object]
|
57
|
-
end
|
58
|
-
options[:template] = template
|
59
|
-
# if prefix is active_scaffold_overrides we must try to render with this prefix in following paths
|
60
|
-
if prefix != 'active_scaffold_overrides'
|
61
|
-
options[:prefixes] = lookup_context.prefixes.drop((lookup_context.prefixes.find_index(prefix) || -1) + 1)
|
62
|
-
else
|
63
|
-
options[:prefixes] = ['active_scaffold_overrides']
|
64
|
-
last_view_path = File.expand_path(File.dirname(File.dirname(lookup_context.last_template.inspect)), Rails.root)
|
65
|
-
new_view_paths = view_paths.drop(view_paths.find_index { |path| path.to_s == last_view_path } + 1)
|
66
|
-
if @lookup_context
|
67
|
-
@lookup_context = build_lookup_context(new_view_paths)
|
68
|
-
else
|
69
|
-
lookup_context.view_paths = new_view_paths
|
70
|
-
end
|
71
|
-
end
|
72
|
-
result = super options
|
48
|
+
result = super options_for_render_super(args[1])
|
73
49
|
@lookup_context = @_lookup_context if @_lookup_context # rails 6
|
74
50
|
lookup_context.view_paths = @_view_paths if @_view_paths # rails < 6
|
75
51
|
lookup_context.last_template = @_last_template if @_last_template # rails < 6
|
@@ -103,6 +79,46 @@ module ActiveScaffold #:nodoc:
|
|
103
79
|
|
104
80
|
private
|
105
81
|
|
82
|
+
def options_for_render_super(options)
|
83
|
+
options ||= {}
|
84
|
+
options[:locals] ||= {}
|
85
|
+
if view_stack.last
|
86
|
+
options[:locals] = view_stack.last[:locals].merge!(options[:locals]) if view_stack.last[:locals]
|
87
|
+
options[:object] ||= view_stack.last[:object] if view_stack.last[:object]
|
88
|
+
end
|
89
|
+
|
90
|
+
parts = @virtual_path.split('/')
|
91
|
+
options[:template] = parts.pop
|
92
|
+
prefix = parts.join('/')
|
93
|
+
# if prefix is active_scaffold_overrides we must try to render with this prefix in following paths
|
94
|
+
if prefix != 'active_scaffold_overrides'
|
95
|
+
options[:prefixes] = lookup_context.prefixes.drop((lookup_context.prefixes.find_index(prefix) || -1) + 1)
|
96
|
+
else
|
97
|
+
options[:prefixes] = ['active_scaffold_overrides']
|
98
|
+
update_view_paths
|
99
|
+
end
|
100
|
+
options
|
101
|
+
end
|
102
|
+
|
103
|
+
def update_view_paths
|
104
|
+
last_view_path =
|
105
|
+
if @lookup_context # rails 6
|
106
|
+
File.expand_path(File.dirname(File.dirname(@lookup_context.last_template.short_identifier.to_s)), Rails.root)
|
107
|
+
else
|
108
|
+
File.expand_path(File.dirname(File.dirname(lookup_context.last_template.inspect)), Rails.root)
|
109
|
+
end
|
110
|
+
new_view_paths = view_paths.drop(view_paths.find_index { |path| path.to_s == last_view_path } + 1)
|
111
|
+
if @lookup_context # rails 6
|
112
|
+
if respond_to? :build_lookup_context # rails 6.0
|
113
|
+
build_lookup_context(new_view_paths)
|
114
|
+
else # rails 6.1
|
115
|
+
@lookup_context = ActionView::LookupContext.new(new_view_paths)
|
116
|
+
end
|
117
|
+
else
|
118
|
+
lookup_context.view_paths = new_view_paths
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
106
122
|
def render_embedded(options)
|
107
123
|
require 'digest/md5'
|
108
124
|
|
@@ -153,5 +169,30 @@ module ActionView
|
|
153
169
|
Base.class_eval do
|
154
170
|
include ActiveScaffold::RenderingHelper
|
155
171
|
end
|
172
|
+
|
173
|
+
if Gem.loaded_specs['rails'].version.segments.first >= 6
|
174
|
+
RenderingHelper.class_eval do
|
175
|
+
# override the render method to use our @lookup_context instead of the
|
176
|
+
# memoized @_lookup_context
|
177
|
+
def render(options = {}, locals = {}, &block)
|
178
|
+
case options
|
179
|
+
when Hash
|
180
|
+
in_rendering_context(options) do |_|
|
181
|
+
# previously set view paths and lookup context are lost here
|
182
|
+
# if you use view_renderer, so instead create a new renderer
|
183
|
+
# with our context
|
184
|
+
temp_renderer = ActionView::Renderer.new(@lookup_context)
|
185
|
+
if block_given?
|
186
|
+
temp_renderer.render_partial(self, options.merge(partial: options[:layout]), &block)
|
187
|
+
else
|
188
|
+
temp_renderer.render(self, options)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
else
|
192
|
+
view_renderer.render_partial(self, partial: options, locals: locals, &block)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
156
197
|
end
|
157
198
|
end
|
@@ -3,7 +3,7 @@ class Object
|
|
3
3
|
if key.present?
|
4
4
|
scope = [:active_scaffold, *options.delete(:scope)]
|
5
5
|
options = options.reverse_merge(:scope => scope, :default => key.is_a?(String) ? key : key.to_s.titleize)
|
6
|
-
text = I18n.translate(key.to_s, options).html_safe # rubocop:disable Rails/OutputSafety
|
6
|
+
text = I18n.translate(key.to_s, **options).html_safe # rubocop:disable Rails/OutputSafety
|
7
7
|
# text = nil if text.include?('translation missing:')
|
8
8
|
end
|
9
9
|
text || key
|
@@ -409,9 +409,9 @@ module ActiveScaffold
|
|
409
409
|
params_hash active_scaffold_embedded_params[:conditions]
|
410
410
|
end
|
411
411
|
|
412
|
-
def all_conditions
|
412
|
+
def all_conditions(include_id_condition = true)
|
413
413
|
[
|
414
|
-
id_condition,
|
414
|
+
(id_condition if include_id_condition), # for list with id (e.g. /users/:id/index)
|
415
415
|
active_scaffold_conditions, # from the search modules
|
416
416
|
conditions_for_collection, # from the dev
|
417
417
|
conditions_from_params, # from the parameters (e.g. /users/list?first_name=Fred)
|
@@ -444,9 +444,11 @@ module ActiveScaffold
|
|
444
444
|
def finder_options(options = {})
|
445
445
|
search_conditions = all_conditions
|
446
446
|
|
447
|
+
sorting = options[:sorting]&.clause((grouped_columns_calculations if grouped_search?))
|
448
|
+
sorting = sorting.map(&Arel.method(:sql)) if sorting && active_scaffold_config.active_record?
|
447
449
|
# create a general-use options array that's compatible with Rails finders
|
448
450
|
finder_options = {
|
449
|
-
:reorder =>
|
451
|
+
:reorder => sorting,
|
450
452
|
:conditions => search_conditions
|
451
453
|
}
|
452
454
|
if active_scaffold_config.mongoid?
|
@@ -519,8 +521,8 @@ module ActiveScaffold
|
|
519
521
|
@last_modified = query.maximum(:updated_at)
|
520
522
|
end
|
521
523
|
|
522
|
-
def calculate_query
|
523
|
-
conditions = all_conditions
|
524
|
+
def calculate_query(id_condition = true)
|
525
|
+
conditions = all_conditions(id_condition)
|
524
526
|
includes = active_scaffold_config.list.count_includes
|
525
527
|
includes ||= active_scaffold_references if conditions.present?
|
526
528
|
left_joins = active_scaffold_outer_joins
|
@@ -180,6 +180,17 @@ module ActiveScaffold
|
|
180
180
|
end
|
181
181
|
end
|
182
182
|
end
|
183
|
+
|
184
|
+
def save_record_to_association(record, association, value, reverse = nil)
|
185
|
+
return unless association
|
186
|
+
if association.collection?
|
187
|
+
record.association(association.name).target << value
|
188
|
+
elsif reverse&.belongs_to?
|
189
|
+
value.send("#{reverse.name}=", record)
|
190
|
+
else
|
191
|
+
record.send("#{association.name}=", value)
|
192
|
+
end
|
193
|
+
end
|
183
194
|
end
|
184
195
|
end
|
185
196
|
end
|
@@ -71,9 +71,9 @@ module ActiveScaffold
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
def active_scaffold_subform_attributes(column, column_css_class = nil)
|
74
|
+
def active_scaffold_subform_attributes(column, column_css_class = nil, klass = nil)
|
75
75
|
{
|
76
|
-
:class => "sub-form #{active_scaffold_config_for(column.association.klass).subform.layout}-sub-form #{column_css_class} #{column.name}-sub-form",
|
76
|
+
:class => "sub-form #{active_scaffold_config_for(klass || column.association.klass).subform.layout}-sub-form #{column_css_class} #{column.name}-sub-form",
|
77
77
|
:id => sub_form_id(:association => column.name)
|
78
78
|
}
|
79
79
|
end
|
@@ -308,17 +308,39 @@ module ActiveScaffold
|
|
308
308
|
html
|
309
309
|
end
|
310
310
|
|
311
|
-
def active_scaffold_new_record_subform(column, record, html_options)
|
312
|
-
|
311
|
+
def active_scaffold_new_record_subform(column, record, html_options, new_record_attributes: nil, locals: {}, skip_link: false) # rubocop:disable Metrics/ParameterLists
|
312
|
+
klass =
|
313
|
+
if column.association.polymorphic? && column.association.belongs_to?
|
314
|
+
type = record.send(column.association.foreign_type)
|
315
|
+
column.association.klass(record) if type.present? && (column.options[:add_new] == true || type.in?(column.options[:add_new]))
|
316
|
+
else
|
317
|
+
column.association.klass
|
318
|
+
end
|
319
|
+
return content_tag(:div, '') unless klass
|
320
|
+
subform_attrs = active_scaffold_subform_attributes(column, nil, klass)
|
321
|
+
if record.send(column.name)&.new_record?
|
322
|
+
new_record = record.send(column.name)
|
323
|
+
else
|
324
|
+
subform_attrs[:style] = 'display: none'
|
325
|
+
end
|
326
|
+
subform_attrs[:class] << ' optional'
|
313
327
|
scope = html_options[:name].scan(/record(.*)\[#{column.name}\]/).dig(0, 0)
|
314
|
-
new_record
|
315
|
-
|
328
|
+
new_record ||= klass.new(new_record_attributes)
|
329
|
+
locals = locals.reverse_merge(column: column, parent_record: record, associated: [], show_blank_record: new_record, scope: scope)
|
330
|
+
subform = render(partial: subform_partial_for_column(column, klass), locals: locals)
|
331
|
+
if column.options[:hide_subgroups]
|
332
|
+
toggable_id = "#{sub_form_id(association: column.name, id: record.id || generated_id(record) || 99_999_999_999)}-div"
|
333
|
+
subform << link_to_visibility_toggle(toggable_id, default_visible: false)
|
334
|
+
end
|
316
335
|
html = content_tag(:div, subform, subform_attrs)
|
336
|
+
return html if skip_link
|
317
337
|
html << active_scaffold_show_new_subform_link(column, record, html_options[:id], subform_attrs[:id])
|
318
338
|
end
|
319
339
|
|
320
340
|
def active_scaffold_show_new_subform_link(column, record, select_id, subform_id)
|
321
|
-
|
341
|
+
data = {select_id: select_id, subform_id: subform_id, subform_text: as_(:add_existing), select_text: as_(:create_new)}
|
342
|
+
label = data[record.send(column.name)&.new_record? ? :subform_text : :select_text]
|
343
|
+
link_to(label, '#', data: data, class: 'show-new-subform')
|
322
344
|
end
|
323
345
|
|
324
346
|
def active_scaffold_file_with_remove_link(column, options, content, remove_file_prefix, controls_class, &block) # rubocop:disable Metrics/ParameterLists
|
@@ -469,20 +491,35 @@ module ActiveScaffold
|
|
469
491
|
active_scaffold_enum_options(column, record)
|
470
492
|
end
|
471
493
|
|
472
|
-
selected = record.send(column.association.name)
|
494
|
+
selected = record.send(column.association.name) if column.association
|
495
|
+
selected_id = selected&.id
|
473
496
|
if options.present?
|
497
|
+
if column.options[:add_new]
|
498
|
+
html_options[:data] ||= {}
|
499
|
+
html_options[:data][:subform_id] = active_scaffold_subform_attributes(column)[:id]
|
500
|
+
radio_html_options = html_options.merge(class: html_options[:class] + ' hide-new-subform')
|
501
|
+
else
|
502
|
+
radio_html_options = html_options
|
503
|
+
end
|
474
504
|
radios = options.map do |option|
|
475
|
-
active_scaffold_radio_option(option,
|
505
|
+
active_scaffold_radio_option(option, selected_id, column, radio_html_options)
|
476
506
|
end
|
477
507
|
if column.options[:include_blank]
|
478
508
|
label = column.options[:include_blank]
|
479
509
|
label = as_(column.options[:include_blank]) if column.options[:include_blank].is_a?(Symbol)
|
480
510
|
radios.prepend content_tag(:label, radio_button(:record, column.name, '', html_options.merge(id: nil)) + label)
|
481
511
|
end
|
512
|
+
if column.options[:add_new]
|
513
|
+
create_new_button = radio_button_tag(html_options[:name], '', selected&.new_record?, html_options.merge(id: nil, class: html_options[:class] + ' show-new-subform'))
|
514
|
+
radios << content_tag(:label, create_new_button << as_(:create_new)) <<
|
515
|
+
active_scaffold_new_record_subform(column, record, html_options, skip_link: true)
|
516
|
+
end
|
482
517
|
safe_join radios
|
483
518
|
else
|
484
|
-
content_tag(:span, as_(:no_options), :class => "#{html_options[:class]} no-options", :id => html_options[:id])
|
485
|
-
|
519
|
+
html = content_tag(:span, as_(:no_options), :class => "#{html_options[:class]} no-options", :id => html_options[:id])
|
520
|
+
html << hidden_field_tag(html_options[:name], '', :id => nil)
|
521
|
+
html << active_scaffold_new_record_subform(column, record, html_options) if column.options[:add_new]
|
522
|
+
html
|
486
523
|
end
|
487
524
|
end
|
488
525
|
|
@@ -628,8 +665,8 @@ module ActiveScaffold
|
|
628
665
|
end
|
629
666
|
alias override_input? override_input
|
630
667
|
|
631
|
-
def subform_partial_for_column(column)
|
632
|
-
subform_partial = "#{active_scaffold_config_for(column.association.klass).subform.layout}_subform"
|
668
|
+
def subform_partial_for_column(column, klass = nil)
|
669
|
+
subform_partial = "#{column.options[:layout] || active_scaffold_config_for(klass || column.association.klass).subform.layout}_subform"
|
633
670
|
override_subform_partial(column, subform_partial) || subform_partial
|
634
671
|
end
|
635
672
|
|
@@ -703,14 +740,14 @@ module ActiveScaffold
|
|
703
740
|
|
704
741
|
# Minimum
|
705
742
|
unless options[:min]
|
706
|
-
min = validators.map { |v| v.options[:
|
743
|
+
min = validators.map { |v| v.options[:greater_than_or_equal_to] }.compact.max
|
707
744
|
greater_than = validators.map { |v| v.options[:greater_than] }.compact.max
|
708
745
|
numerical_constraints[:min] = [min, (greater_than + margin if greater_than)].compact.max
|
709
746
|
end
|
710
747
|
|
711
748
|
# Maximum
|
712
749
|
unless options[:max]
|
713
|
-
max = validators.map { |v| v.options[:
|
750
|
+
max = validators.map { |v| v.options[:less_than_or_equal_to] }.compact.min
|
714
751
|
less_than = validators.map { |v| v.options[:less_than] }.compact.min
|
715
752
|
numerical_constraints[:max] = [max, (less_than - margin if less_than)].compact.min
|
716
753
|
end
|
@@ -170,8 +170,12 @@ module ActiveScaffold
|
|
170
170
|
|
171
171
|
def column_association_size(record, column, value)
|
172
172
|
cached_counts = @counts&.dig(column.name)
|
173
|
-
|
174
|
-
|
173
|
+
if cached_counts
|
174
|
+
key = column.association.primary_key if count_on_association_class?(column)
|
175
|
+
cached_counts[record.send(key || :id)] || 0
|
176
|
+
else
|
177
|
+
value.size
|
178
|
+
end
|
175
179
|
end
|
176
180
|
|
177
181
|
def format_number_value(value, options = {})
|
@@ -427,16 +431,16 @@ module ActiveScaffold
|
|
427
431
|
|
428
432
|
# CALCULATIONS
|
429
433
|
|
430
|
-
def column_calculation(column)
|
434
|
+
def column_calculation(column, id_condition: true)
|
431
435
|
if column.calculate.instance_of? Proc
|
432
436
|
column.calculate.call(@records)
|
433
437
|
else
|
434
|
-
calculate_query.calculate(column.calculate, column.name)
|
438
|
+
calculate_query(id_condition).calculate(column.calculate, column.name)
|
435
439
|
end
|
436
440
|
end
|
437
441
|
|
438
|
-
def render_column_calculation(column)
|
439
|
-
calculation = column_calculation(column)
|
442
|
+
def render_column_calculation(column, id_condition: true)
|
443
|
+
calculation = column_calculation(column, id_condition: id_condition)
|
440
444
|
override_formatter = "render_#{column.name}_#{column.calculate.is_a?(Proc) ? :calculate : column.calculate}"
|
441
445
|
calculation = send(override_formatter, calculation) if respond_to? override_formatter
|
442
446
|
format_column_calculation(column, calculation)
|