active_scaffold 3.6.20 → 3.7.1
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 +47 -0
- data/README.md +29 -16
- data/app/assets/javascripts/jquery/active_scaffold.js +106 -68
- data/app/assets/javascripts/jquery/active_scaffold_chosen.js +6 -5
- data/app/assets/javascripts/jquery/tiny_mce_bridge.js +18 -4
- data/app/assets/stylesheets/active_scaffold_layout.css +13 -2
- data/app/views/active_scaffold_overrides/_base_form.html.erb +5 -1
- data/app/views/active_scaffold_overrides/_field_search.html.erb +1 -0
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_render_field.js.erb +24 -13
- data/config/locales/de.yml +6 -3
- data/config/locales/en.yml +3 -0
- data/config/locales/es.yml +3 -0
- data/config/locales/fr.yml +9 -6
- data/config/locales/hu.yml +20 -17
- data/config/locales/ja.yml +83 -80
- data/config/locales/ru.yml +17 -14
- data/lib/active_scaffold/actions/common_search.rb +2 -2
- data/lib/active_scaffold/actions/core.rb +30 -10
- data/lib/active_scaffold/actions/field_search.rb +9 -6
- data/lib/active_scaffold/actions/nested.rb +7 -7
- data/lib/active_scaffold/actions/update.rb +3 -3
- data/lib/active_scaffold/attribute_params.rb +22 -70
- data/lib/active_scaffold/bridges/active_storage/active_storage_helpers.rb +0 -3
- data/lib/active_scaffold/bridges/active_storage/form_ui.rb +6 -6
- data/lib/active_scaffold/bridges/active_storage/list_ui.rb +7 -7
- data/lib/active_scaffold/bridges/active_storage.rb +3 -0
- data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +2 -2
- data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +2 -2
- data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +12 -14
- data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +2 -2
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/chosen/helpers.rb +10 -10
- data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +7 -7
- data/lib/active_scaffold/bridges/date_picker/ext.rb +20 -9
- data/lib/active_scaffold/bridges/date_picker/helper.rb +9 -9
- data/lib/active_scaffold/bridges/date_picker.rb +2 -0
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -3
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +5 -5
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/list_ui.rb +3 -3
- data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +1 -1
- data/lib/active_scaffold/bridges/paper_trail/actions.rb +4 -1
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -3
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/record_select/helpers.rb +17 -17
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +6 -6
- data/lib/active_scaffold/bridges/tiny_mce.rb +1 -1
- data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +6 -11
- data/lib/active_scaffold/bridges.rb +0 -3
- data/lib/active_scaffold/config/core.rb +1 -1
- data/lib/active_scaffold/config/field_search.rb +9 -1
- data/lib/active_scaffold/config/form.rb +9 -1
- data/lib/active_scaffold/constraints.rb +22 -7
- data/lib/active_scaffold/core.rb +6 -10
- data/lib/active_scaffold/data_structures/action_columns.rb +0 -25
- data/lib/active_scaffold/data_structures/action_links.rb +1 -1
- data/lib/active_scaffold/data_structures/association/abstract.rb +8 -0
- data/lib/active_scaffold/data_structures/association/active_mongoid.rb +8 -0
- data/lib/active_scaffold/data_structures/association/active_record.rb +1 -13
- data/lib/active_scaffold/data_structures/association/mongoid.rb +21 -8
- data/lib/active_scaffold/data_structures/column.rb +139 -28
- data/lib/active_scaffold/data_structures/columns.rb +12 -12
- data/lib/active_scaffold/data_structures/nested_info.rb +12 -0
- data/lib/active_scaffold/data_structures/sorting.rb +1 -1
- data/lib/active_scaffold/engine.rb +15 -1
- data/lib/active_scaffold/extensions/action_view_rendering.rb +13 -5
- data/lib/active_scaffold/extensions/cow_proxy.rb +1 -1
- data/lib/active_scaffold/extensions/routing_mapper.rb +1 -0
- data/lib/active_scaffold/extensions/unsaved_record.rb +9 -3
- data/lib/active_scaffold/finder.rb +147 -28
- data/lib/active_scaffold/helpers/action_link_helpers.rb +1 -1
- data/lib/active_scaffold/helpers/controller_helpers.rb +9 -4
- data/lib/active_scaffold/helpers/form_column_helpers.rb +153 -107
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +48 -14
- data/lib/active_scaffold/helpers/list_column_helpers.rb +37 -20
- data/lib/active_scaffold/helpers/search_column_helpers.rb +137 -55
- data/lib/active_scaffold/helpers/show_column_helpers.rb +6 -6
- data/lib/active_scaffold/helpers/view_helpers.rb +1 -1
- data/lib/active_scaffold/orm_checks.rb +21 -1
- data/lib/active_scaffold/registry.rb +10 -15
- data/lib/active_scaffold/tableless.rb +10 -79
- data/lib/active_scaffold/version.rb +2 -2
- data/lib/active_scaffold.rb +3 -9
- data/lib/generators/active_scaffold/install_generator.rb +2 -2
- data/test/bridges/bridge_test.rb +1 -1
- data/test/bridges/date_picker_test.rb +3 -2
- data/test/bridges/paperclip_test.rb +18 -14
- data/test/bridges/tiny_mce_test.rb +5 -3
- data/test/config/base_test.rb +1 -1
- data/test/config/core_test.rb +1 -1
- data/test/config/create_test.rb +1 -1
- data/test/config/delete_test.rb +1 -1
- data/test/config/field_search_test.rb +1 -1
- data/test/config/list_test.rb +1 -1
- data/test/config/nested_test.rb +1 -1
- data/test/config/search_test.rb +1 -1
- data/test/config/show_test.rb +1 -1
- data/test/config/subform_test.rb +1 -1
- data/test/config/update_test.rb +1 -1
- data/test/data_structures/action_columns_test.rb +1 -1
- data/test/data_structures/action_link_test.rb +1 -1
- data/test/data_structures/action_links_test.rb +1 -1
- data/test/data_structures/actions_test.rb +1 -1
- data/test/data_structures/association_column_test.rb +1 -1
- data/test/data_structures/column_test.rb +1 -1
- data/test/data_structures/columns_test.rb +1 -1
- data/test/data_structures/set_test.rb +1 -1
- data/test/data_structures/sorting_test.rb +1 -1
- data/test/data_structures/standard_column_test.rb +1 -1
- data/test/data_structures/validation_reflection_test.rb +1 -1
- data/test/data_structures/virtual_column_test.rb +1 -1
- data/test/extensions/active_record_test.rb +1 -1
- data/test/helpers/form_column_helpers_test.rb +7 -5
- data/test/helpers/pagination_helpers_test.rb +1 -1
- data/test/helpers/search_column_helpers_test.rb +2 -1
- data/test/misc/active_record_permissions_test.rb +1 -1
- data/test/misc/attribute_params_test.rb +1 -1
- data/test/misc/calculation_test.rb +1 -1
- data/test/misc/configurable_test.rb +1 -1
- data/test/misc/constraints_test.rb +2 -1
- data/test/misc/convert_numbers_format_test.rb +1 -1
- data/test/misc/finder_test.rb +39 -1
- data/test/misc/lang_test.rb +1 -1
- data/test/misc/parse_datetime_test.rb +1 -1
- data/test/misc/tableless_test.rb +1 -1
- data/test/test_helper.rb +4 -4
- metadata +5 -17
- data/config/brakeman.ignore +0 -26
- data/config/brakeman.yml +0 -3
- data/config/i18n-tasks.yml +0 -121
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +0 -221
- data/lib/active_scaffold/delayed_setup.rb +0 -41
- data/lib/active_scaffold/extensions/left_outer_joins.rb +0 -43
|
@@ -40,14 +40,27 @@ module ActiveScaffold::DataStructures
|
|
|
40
40
|
# the display-name of the column. this will be used, for instance, as the column title in the table and as the field name in the form.
|
|
41
41
|
# if left alone it will utilize human_attribute_name which includes localization
|
|
42
42
|
attr_writer :label
|
|
43
|
-
def label
|
|
44
|
-
|
|
43
|
+
def label(record = nil, scope = nil)
|
|
44
|
+
if @label.respond_to?(:call)
|
|
45
|
+
if record
|
|
46
|
+
@label.call(record, self, scope)
|
|
47
|
+
else
|
|
48
|
+
# sometimes label is called without a record in context (ie, from table
|
|
49
|
+
# headers). In this case fall back to the humanized attribute name
|
|
50
|
+
# instead of the Proc
|
|
51
|
+
active_record_class.human_attribute_name(name.to_s)
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
as_(@label) || active_record_class.human_attribute_name(name.to_s)
|
|
55
|
+
end
|
|
45
56
|
end
|
|
46
57
|
|
|
47
58
|
# a textual description of the column and its contents. this will be displayed with any associated form input widget, so you may want to consider adding a content example.
|
|
48
59
|
attr_writer :description
|
|
49
|
-
def description
|
|
50
|
-
if @description
|
|
60
|
+
def description(record = nil, scope = nil)
|
|
61
|
+
if @description&.respond_to?(:call)
|
|
62
|
+
@description.call(record, self, scope)
|
|
63
|
+
elsif @description
|
|
51
64
|
@description
|
|
52
65
|
else
|
|
53
66
|
I18n.t name, :scope => [:activerecord, :description, active_record_class.to_s.underscore.to_sym], :default => ''
|
|
@@ -87,6 +100,19 @@ module ActiveScaffold::DataStructures
|
|
|
87
100
|
cattr_accessor :send_form_on_update_column, instance_accessor: false
|
|
88
101
|
attr_accessor :send_form_on_update_column
|
|
89
102
|
|
|
103
|
+
# add a custom attr_accessor that can contain a Proc (or boolean or symbol)
|
|
104
|
+
# that will be called when the column renders, such that we can dynamically
|
|
105
|
+
# hide or show the column with an element that can be replaced by
|
|
106
|
+
# update_columns, but won't affect the form submission.
|
|
107
|
+
# The value can be set in the scaffold controller as follows to dynamically
|
|
108
|
+
# hide the column based on a Proc's output:
|
|
109
|
+
# config.columns[:my_column].hide_form_column_if = Proc.new { |record, column, scope| record.vehicle_type == 'tractor' }
|
|
110
|
+
# OR to always hide the column:
|
|
111
|
+
# config.columns[:my_column].hide_form_column_if = true
|
|
112
|
+
# OR to call a method on the record to determine whether to hide the column:
|
|
113
|
+
# config.columns[:my_column].hide_form_column_if = :hide_tractor_fields?
|
|
114
|
+
attr_accessor :hide_form_column_if
|
|
115
|
+
|
|
90
116
|
# sorting on a column can be configured four ways:
|
|
91
117
|
# sort = true default, uses intelligent sorting sql default
|
|
92
118
|
# sort = false sometimes sorting doesn't make sense
|
|
@@ -118,24 +144,58 @@ module ActiveScaffold::DataStructures
|
|
|
118
144
|
# supported options:
|
|
119
145
|
# * for association columns
|
|
120
146
|
# * :select - displays a simple <select> or a collection of checkboxes to (dis)associate records
|
|
121
|
-
|
|
147
|
+
attr_reader :form_ui
|
|
148
|
+
|
|
149
|
+
attr_reader :form_ui_options
|
|
122
150
|
|
|
123
|
-
|
|
151
|
+
# value must be a Symbol, or an Array of form_ui and options hash which will be used with form_ui only
|
|
152
|
+
def form_ui=(value)
|
|
153
|
+
check_valid_action_ui_params(value)
|
|
154
|
+
@form_ui, @form_ui_options = *value
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# value must be a Symbol, or an Array of list_ui and options hash which will be used with list_ui only
|
|
158
|
+
def list_ui=(value)
|
|
159
|
+
check_valid_action_ui_params(value)
|
|
160
|
+
@list_ui, @list_ui_options = *value
|
|
161
|
+
end
|
|
124
162
|
|
|
125
163
|
def list_ui
|
|
126
164
|
@list_ui || form_ui
|
|
127
165
|
end
|
|
128
166
|
|
|
129
|
-
|
|
167
|
+
def list_ui_options
|
|
168
|
+
@list_ui ? @list_ui_options : form_ui_options
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# value must be a Symbol, or an Array of show_ui and options hash which will be used with show_ui only
|
|
172
|
+
def show_ui=(value)
|
|
173
|
+
check_valid_action_ui_params(value)
|
|
174
|
+
@show_ui, @show_ui_options = *value
|
|
175
|
+
end
|
|
176
|
+
|
|
130
177
|
def show_ui
|
|
131
178
|
@show_ui || list_ui
|
|
132
179
|
end
|
|
133
180
|
|
|
134
|
-
|
|
181
|
+
def show_ui_options
|
|
182
|
+
@show_ui ? @show_ui_options : list_ui_options
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# value must be a Symbol, or an Array of search_ui and options hash which will be used with search_ui only
|
|
186
|
+
def search_ui=(value)
|
|
187
|
+
check_valid_action_ui_params(value)
|
|
188
|
+
@search_ui, @search_ui_options = *value
|
|
189
|
+
end
|
|
190
|
+
|
|
135
191
|
def search_ui
|
|
136
192
|
@search_ui || @form_ui || (:select if association && !association.polymorphic?)
|
|
137
193
|
end
|
|
138
194
|
|
|
195
|
+
def search_ui_options
|
|
196
|
+
@search_ui ? @search_ui_options : form_ui_options
|
|
197
|
+
end
|
|
198
|
+
|
|
139
199
|
# a place to store dev's column specific options
|
|
140
200
|
attr_writer :options
|
|
141
201
|
def options
|
|
@@ -314,6 +374,9 @@ module ActiveScaffold::DataStructures
|
|
|
314
374
|
@name = name.to_sym
|
|
315
375
|
@active_record_class = active_record_class
|
|
316
376
|
@column = _columns_hash[name.to_s]
|
|
377
|
+
if @column.nil? && active_record? && active_record_class._default_attributes.key?(name.to_s)
|
|
378
|
+
@column = active_record_class._default_attributes[name.to_s]
|
|
379
|
+
end
|
|
317
380
|
@delegated_association = delegated_association
|
|
318
381
|
@cache_key = [@active_record_class.name, name].compact.map(&:to_s).join('#')
|
|
319
382
|
setup_association_info
|
|
@@ -328,24 +391,9 @@ module ActiveScaffold::DataStructures
|
|
|
328
391
|
@actions_for_association_links = self.class.actions_for_association_links.dup if association
|
|
329
392
|
@select_columns = default_select_columns
|
|
330
393
|
|
|
331
|
-
@text = @column.nil? || [:string, :text, String].include?(column_type)
|
|
394
|
+
@text = @column.nil? || [:string, :text, :citext, String].include?(column_type)
|
|
332
395
|
@number = false
|
|
333
|
-
if @column
|
|
334
|
-
if active_record_class.respond_to?(:defined_enums) && active_record_class.defined_enums[name.to_s]
|
|
335
|
-
@form_ui = :select
|
|
336
|
-
@options = {:options => active_record_class.send(name.to_s.pluralize).keys.map(&:to_sym)}
|
|
337
|
-
elsif column_number?
|
|
338
|
-
@number = true
|
|
339
|
-
@form_ui = :number
|
|
340
|
-
@options = {:format => :i18n_number}
|
|
341
|
-
else
|
|
342
|
-
@form_ui =
|
|
343
|
-
case @column.type
|
|
344
|
-
when :boolean then :checkbox
|
|
345
|
-
when :text then :textarea
|
|
346
|
-
end
|
|
347
|
-
end
|
|
348
|
-
end
|
|
396
|
+
setup_defaults_for_column if @column
|
|
349
397
|
@allow_add_existing = true
|
|
350
398
|
@form_ui = self.class.association_form_ui if @association && self.class.association_form_ui
|
|
351
399
|
|
|
@@ -370,7 +418,7 @@ module ActiveScaffold::DataStructures
|
|
|
370
418
|
# just the field (not table.field)
|
|
371
419
|
def field_name
|
|
372
420
|
return nil if virtual?
|
|
373
|
-
@field_name ||= column ? quoted_field_name(column.name) : association.foreign_key
|
|
421
|
+
@field_name ||= column ? quoted_field_name(column.name) : quoted_field_name(association.foreign_key)
|
|
374
422
|
end
|
|
375
423
|
|
|
376
424
|
def <=>(other)
|
|
@@ -404,7 +452,22 @@ module ActiveScaffold::DataStructures
|
|
|
404
452
|
end
|
|
405
453
|
|
|
406
454
|
def default_for_empty_value
|
|
407
|
-
|
|
455
|
+
return nil unless column
|
|
456
|
+
if column.is_a?(ActiveModel::Attribute)
|
|
457
|
+
column.value
|
|
458
|
+
elsif active_record?
|
|
459
|
+
null? ? nil : column.default
|
|
460
|
+
elsif mongoid?
|
|
461
|
+
column.default_val
|
|
462
|
+
end
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def null?
|
|
466
|
+
if active_record? && !column.is_a?(ActiveModel::Attribute)
|
|
467
|
+
column&.null
|
|
468
|
+
else
|
|
469
|
+
true
|
|
470
|
+
end
|
|
408
471
|
end
|
|
409
472
|
|
|
410
473
|
# the table.field name for this column, if applicable
|
|
@@ -412,6 +475,10 @@ module ActiveScaffold::DataStructures
|
|
|
412
475
|
@field ||= quoted_field(field_name)
|
|
413
476
|
end
|
|
414
477
|
|
|
478
|
+
def quoted_foreign_type
|
|
479
|
+
quoted_field(quoted_field_name(association.foreign_type))
|
|
480
|
+
end
|
|
481
|
+
|
|
415
482
|
def type_for_attribute
|
|
416
483
|
ActiveScaffold::OrmChecks.type_for_attribute active_record_class, name
|
|
417
484
|
end
|
|
@@ -420,8 +487,39 @@ module ActiveScaffold::DataStructures
|
|
|
420
487
|
ActiveScaffold::OrmChecks.column_type active_record_class, name
|
|
421
488
|
end
|
|
422
489
|
|
|
490
|
+
def default_value
|
|
491
|
+
ActiveScaffold::OrmChecks.column_type active_record_class, name
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
def attributes=(opts)
|
|
495
|
+
opts.each do |setting, value|
|
|
496
|
+
send "#{setting}=", value
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
def cast(value)
|
|
501
|
+
ActiveScaffold::OrmChecks.cast active_record_class, name, value
|
|
502
|
+
end
|
|
503
|
+
|
|
423
504
|
protected
|
|
424
505
|
|
|
506
|
+
def setup_defaults_for_column
|
|
507
|
+
if active_record_class.respond_to?(:defined_enums) && active_record_class.defined_enums[name.to_s]
|
|
508
|
+
@form_ui = :select
|
|
509
|
+
@options = {:options => active_record_class.send(name.to_s.pluralize).keys.map(&:to_sym)}
|
|
510
|
+
elsif column_number?
|
|
511
|
+
@number = true
|
|
512
|
+
@form_ui = :number
|
|
513
|
+
@options = {:format => :i18n_number}
|
|
514
|
+
else
|
|
515
|
+
@form_ui =
|
|
516
|
+
case column_type
|
|
517
|
+
when :boolean then null? ? :boolean : :checkbox
|
|
518
|
+
when :text then :textarea
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
end
|
|
522
|
+
|
|
425
523
|
def setup_association_info
|
|
426
524
|
assoc = active_record_class.reflect_on_association(name)
|
|
427
525
|
@association =
|
|
@@ -480,7 +578,7 @@ module ActiveScaffold::DataStructures
|
|
|
480
578
|
end
|
|
481
579
|
|
|
482
580
|
def column_number?
|
|
483
|
-
return %i[float decimal integer].include?
|
|
581
|
+
return %i[float decimal integer].include? column_type if active_record?
|
|
484
582
|
return @column.type < Numeric if mongoid?
|
|
485
583
|
end
|
|
486
584
|
|
|
@@ -534,5 +632,18 @@ module ActiveScaffold::DataStructures
|
|
|
534
632
|
300
|
|
535
633
|
end
|
|
536
634
|
end
|
|
635
|
+
|
|
636
|
+
def check_valid_action_ui_params(value)
|
|
637
|
+
return true if valid_action_ui_params?(value)
|
|
638
|
+
raise ArgumentError, 'value must be a Symbol, or an array of Symbol and Hash'
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
def valid_action_ui_params?(value)
|
|
642
|
+
if value.is_a?(Array)
|
|
643
|
+
value.size <= 2 && value[0].is_a?(Symbol) && (value[1].nil? || value[1].is_a?(Hash))
|
|
644
|
+
else
|
|
645
|
+
value.nil? || value.is_a?(Symbol)
|
|
646
|
+
end
|
|
647
|
+
end
|
|
537
648
|
end
|
|
538
649
|
end
|
|
@@ -13,7 +13,7 @@ module ActiveScaffold::DataStructures
|
|
|
13
13
|
# IT IS NOT MEANT FOR PUBLIC USE (but if you know what you're doing, go ahead)
|
|
14
14
|
def _inheritable=(value)
|
|
15
15
|
@sorted = true
|
|
16
|
-
@_inheritable = value
|
|
16
|
+
@_inheritable = ::Set.new(value)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
# This accessor is used by ActionColumns to create new Column objects without adding them to this set
|
|
@@ -21,8 +21,8 @@ module ActiveScaffold::DataStructures
|
|
|
21
21
|
|
|
22
22
|
def initialize(active_record_class, *args)
|
|
23
23
|
@active_record_class = active_record_class
|
|
24
|
-
@_inheritable =
|
|
25
|
-
@set =
|
|
24
|
+
@_inheritable = ::Set.new
|
|
25
|
+
@set = {}
|
|
26
26
|
@sorted = nil
|
|
27
27
|
|
|
28
28
|
add(*args)
|
|
@@ -35,9 +35,11 @@ module ActiveScaffold::DataStructures
|
|
|
35
35
|
args = args.collect(&:to_sym)
|
|
36
36
|
|
|
37
37
|
# make the columns inheritable
|
|
38
|
-
@_inheritable.
|
|
38
|
+
@_inheritable.merge(args)
|
|
39
39
|
# then add columns to @set (unless they already exist)
|
|
40
|
-
args.each
|
|
40
|
+
args.each do |a|
|
|
41
|
+
@set[a.to_sym] = ActiveScaffold::DataStructures::Column.new(a, @active_record_class) unless find_by_name(a)
|
|
42
|
+
end
|
|
41
43
|
end
|
|
42
44
|
alias << add
|
|
43
45
|
|
|
@@ -55,7 +57,7 @@ module ActiveScaffold::DataStructures
|
|
|
55
57
|
klass = column.association.klass
|
|
56
58
|
columns.each do |col|
|
|
57
59
|
next if find_by_name col
|
|
58
|
-
@set
|
|
60
|
+
@set[col.to_sym] = ActiveScaffold::DataStructures::Column.new(col, klass, column.association)
|
|
59
61
|
end
|
|
60
62
|
end
|
|
61
63
|
|
|
@@ -66,24 +68,22 @@ module ActiveScaffold::DataStructures
|
|
|
66
68
|
|
|
67
69
|
# returns an array of columns with the provided names
|
|
68
70
|
def find_by_names(*names)
|
|
69
|
-
|
|
71
|
+
names.map { |name| find_by_name name }
|
|
70
72
|
end
|
|
71
73
|
|
|
72
74
|
# returns the column of the given name.
|
|
73
75
|
def find_by_name(name)
|
|
74
|
-
|
|
75
|
-
column = @set.find { |c| c == name }
|
|
76
|
-
column
|
|
76
|
+
@set[name.to_sym]
|
|
77
77
|
end
|
|
78
78
|
alias [] find_by_name
|
|
79
79
|
|
|
80
80
|
def each
|
|
81
|
-
@set.
|
|
81
|
+
@set.each_value { |name| yield name }
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
def _inheritable
|
|
85
85
|
if @sorted
|
|
86
|
-
@_inheritable
|
|
86
|
+
@_inheritable.to_a
|
|
87
87
|
else
|
|
88
88
|
@_inheritable.sort do |a, b|
|
|
89
89
|
self[a] <=> self[b]
|
|
@@ -70,6 +70,10 @@ module ActiveScaffold::DataStructures
|
|
|
70
70
|
def match_model?(model)
|
|
71
71
|
false
|
|
72
72
|
end
|
|
73
|
+
|
|
74
|
+
def create_with_parent?
|
|
75
|
+
false
|
|
76
|
+
end
|
|
73
77
|
end
|
|
74
78
|
|
|
75
79
|
class NestedInfoAssociation < NestedInfo
|
|
@@ -104,6 +108,14 @@ module ActiveScaffold::DataStructures
|
|
|
104
108
|
association.through_singular? && source_reflection.reverse
|
|
105
109
|
end
|
|
106
110
|
|
|
111
|
+
def create_with_parent?
|
|
112
|
+
if has_many? && !association.through?
|
|
113
|
+
false
|
|
114
|
+
elsif child_association || create_through_singular?
|
|
115
|
+
true
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
107
119
|
def source_reflection
|
|
108
120
|
@source_reflection ||= ActiveScaffold::DataStructures::Association::ActiveRecord.new(association.source_reflection)
|
|
109
121
|
end
|
|
@@ -41,7 +41,7 @@ module ActiveScaffold::DataStructures
|
|
|
41
41
|
column = get_column(column_name)
|
|
42
42
|
raise ArgumentError, "Could not find column #{column_name}" if column.nil?
|
|
43
43
|
raise ArgumentError, 'Sorting direction unknown' unless %i[ASC DESC].include? direction.to_sym
|
|
44
|
-
@clauses << [column, direction
|
|
44
|
+
@clauses << [column, direction] if column.sortable?
|
|
45
45
|
raise ArgumentError, "Can't mix :method- and :sql-based sorting" if mixed_sorting?
|
|
46
46
|
end
|
|
47
47
|
|
|
@@ -2,8 +2,10 @@ module ActiveScaffold
|
|
|
2
2
|
class Engine < ::Rails::Engine
|
|
3
3
|
initializer 'active_scaffold.action_controller' do
|
|
4
4
|
ActiveSupport.on_load :action_controller do
|
|
5
|
+
require 'active_scaffold/extensions/action_controller_rescueing'
|
|
6
|
+
require 'active_scaffold/extensions/action_controller_rendering'
|
|
7
|
+
require 'active_scaffold/extensions/routing_mapper'
|
|
5
8
|
include ActiveScaffold::Core
|
|
6
|
-
include ActiveScaffold::DelayedSetup if ActiveScaffold.delayed_setup
|
|
7
9
|
include ActiveScaffold::RespondsToParent
|
|
8
10
|
include ActiveScaffold::Helpers::ControllerHelpers
|
|
9
11
|
include ActiveScaffold::ActiveRecordPermissions::ModelUserAccess::Controller
|
|
@@ -13,12 +15,17 @@ module ActiveScaffold
|
|
|
13
15
|
|
|
14
16
|
initializer 'active_scaffold.action_view' do
|
|
15
17
|
ActiveSupport.on_load :action_view do
|
|
18
|
+
require 'active_scaffold/extensions/action_view_rendering'
|
|
19
|
+
require 'active_scaffold/extensions/name_option_for_datetime'
|
|
16
20
|
include ActiveScaffold::Helpers::ViewHelpers
|
|
17
21
|
end
|
|
18
22
|
end
|
|
19
23
|
|
|
20
24
|
initializer 'active_scaffold.active_record' do
|
|
21
25
|
ActiveSupport.on_load :active_record do
|
|
26
|
+
require 'active_scaffold/extensions/to_label'
|
|
27
|
+
require 'active_scaffold/extensions/unsaved_associated'
|
|
28
|
+
require 'active_scaffold/extensions/unsaved_record'
|
|
22
29
|
include ActiveScaffold::ActiveRecordPermissions::ModelUserAccess::Model
|
|
23
30
|
module ActiveRecord::Associations
|
|
24
31
|
Association.send :include, ActiveScaffold::Tableless::Association
|
|
@@ -40,5 +47,12 @@ module ActiveScaffold
|
|
|
40
47
|
initializer 'active_scaffold.assets' do
|
|
41
48
|
config.assets.precompile << 'active_scaffold/indicator.gif'
|
|
42
49
|
end
|
|
50
|
+
|
|
51
|
+
initializer 'active_scaffold.extensions' do
|
|
52
|
+
require 'active_scaffold/extensions/cow_proxy'
|
|
53
|
+
require 'active_scaffold/extensions/ice_nine'
|
|
54
|
+
require 'active_scaffold/extensions/localize'
|
|
55
|
+
require 'active_scaffold/extensions/paginator_extensions'
|
|
56
|
+
end
|
|
43
57
|
end
|
|
44
58
|
end
|
|
@@ -119,6 +119,17 @@ module ActiveScaffold #:nodoc:
|
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
+
def remote_controller_config(controller_path)
|
|
123
|
+
# attempt to retrieve the active_scaffold_config by constantizing the controller path
|
|
124
|
+
"#{controller_path}_controller".camelize.constantize.active_scaffold_config
|
|
125
|
+
rescue NameError
|
|
126
|
+
# if we couldn't determine the controller config by instantiating the
|
|
127
|
+
# controller class, parse the ActiveRecord model name from the
|
|
128
|
+
# controller path, which might be a namespaced controller (e.g., 'admin/admins')
|
|
129
|
+
model = controller_path.to_s.sub(%r{.*/}, '').singularize
|
|
130
|
+
active_scaffold_config_for(model)
|
|
131
|
+
end
|
|
132
|
+
|
|
122
133
|
def render_embedded(options)
|
|
123
134
|
require 'digest/md5'
|
|
124
135
|
|
|
@@ -144,13 +155,10 @@ module ActiveScaffold #:nodoc:
|
|
|
144
155
|
else
|
|
145
156
|
url = url_for(url_options)
|
|
146
157
|
content_tag(:div, :id => id, :class => 'active-scaffold-component', :data => {:refresh => url}) do
|
|
147
|
-
# parse the ActiveRecord model name from the controller path, which
|
|
148
|
-
# might be a namespaced controller (e.g., 'admin/admins')
|
|
149
|
-
model = remote_controller.to_s.sub(%r{.*/}, '').singularize
|
|
150
158
|
content_tag(:div, :class => 'active-scaffold-header') do
|
|
151
159
|
content_tag(:h2) do
|
|
152
|
-
|
|
153
|
-
link_to(
|
|
160
|
+
label = options[:label] || remote_controller_config(remote_controller).list.label
|
|
161
|
+
link_to(label, url, remote: true, class: 'load-embedded', data: {error_msg: as_(:error_500)}) <<
|
|
154
162
|
loading_indicator_tag(url_options)
|
|
155
163
|
end
|
|
156
164
|
end
|
|
@@ -49,7 +49,7 @@ module CowProxy
|
|
|
49
49
|
class ActionLinks < ::CowProxy::WrapClass(::ActiveScaffold::DataStructures::ActionLinks)
|
|
50
50
|
def method_missing(name, *args, &block)
|
|
51
51
|
CowProxy.debug { "method missing #{name} in #{__getobj__.name}" }
|
|
52
|
-
return super if name
|
|
52
|
+
return super if name.match?(/[!?]$/)
|
|
53
53
|
subgroup =
|
|
54
54
|
if _instance_variable_defined?("@#{name}")
|
|
55
55
|
_instance_variable_get("@#{name}")
|
|
@@ -11,15 +11,21 @@ module ActiveScaffold::UnsavedRecord
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
# automatically unsets the unsaved flag
|
|
14
|
-
def save(
|
|
14
|
+
def save(**)
|
|
15
15
|
super.tap { self.unsaved = false }
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def keeping_errors
|
|
19
19
|
old_errors = errors.dup if errors.present?
|
|
20
20
|
result = yield
|
|
21
|
-
old_errors&.each do |
|
|
22
|
-
|
|
21
|
+
old_errors&.each do |e|
|
|
22
|
+
if e.is_a?(String) || e.is_a?(Symbol)
|
|
23
|
+
# Rails <6.1 errors API.
|
|
24
|
+
old_errors[e].each { |msg| errors.add(e, msg) unless errors.added?(e, msg) }
|
|
25
|
+
else
|
|
26
|
+
# Rails >=6.1 errors API (https://code.lulalala.com/2020/0531-1013.html).
|
|
27
|
+
errors.add(e.attribute, e.message) unless errors.added?(e.attribute, e.message)
|
|
28
|
+
end
|
|
23
29
|
end
|
|
24
30
|
result && old_errors.blank?
|
|
25
31
|
end
|