active_scaffold 3.6.20 → 3.7.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -12,7 +12,10 @@ module ActiveScaffold::Actions
|
|
12
12
|
def deleted
|
13
13
|
query = PaperTrail::Version.destroys.where(:item_type => active_scaffold_config.model.name)
|
14
14
|
if nested? && nested.child_association&.belongs_to? && PaperTrail::Version.respond_to?(:where_object)
|
15
|
-
|
15
|
+
foreign_key = nested.child_association.foreign_key
|
16
|
+
parent_id = nested.parent_id
|
17
|
+
parent_id = parent_id&.to_i if self.class.active_scaffold_config.columns[foreign_key]&.number?
|
18
|
+
query = query.where_object(foreign_key => parent_id)
|
16
19
|
end
|
17
20
|
pager = Paginator.new(query.count, active_scaffold_config.list.per_page) do |offset, per_page|
|
18
21
|
query.offset(offset).limit(per_page).map(&:reify)
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module ActiveScaffold
|
2
2
|
module Helpers
|
3
3
|
module FormColumnHelpers
|
4
|
-
def active_scaffold_input_paperclip(column, options)
|
4
|
+
def active_scaffold_input_paperclip(column, options, ui_options: column.options)
|
5
5
|
record = options[:object]
|
6
6
|
paperclip = record.send(column.name.to_s)
|
7
|
-
content = active_scaffold_column_paperclip(record, column) if paperclip.file?
|
8
|
-
active_scaffold_file_with_remove_link(column, options, content, 'delete_', 'paperclip_controls')
|
7
|
+
content = active_scaffold_column_paperclip(record, column, ui_options: ui_options) if paperclip.file?
|
8
|
+
active_scaffold_file_with_remove_link(column, options, content, 'delete_', 'paperclip_controls', ui_options: ui_options)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActiveScaffold
|
2
2
|
module Helpers
|
3
3
|
module ListColumnHelpers
|
4
|
-
def active_scaffold_column_paperclip(record, column)
|
4
|
+
def active_scaffold_column_paperclip(record, column, ui_options: column.options)
|
5
5
|
paperclip = record.send(column.name.to_s)
|
6
6
|
return nil unless paperclip.file?
|
7
7
|
content =
|
@@ -10,21 +10,21 @@ class ActiveScaffold::Bridges::RecordSelect
|
|
10
10
|
|
11
11
|
module FormColumnHelpers
|
12
12
|
# requires RecordSelect plugin to be installed and configured.
|
13
|
-
def active_scaffold_input_record_select(column, options)
|
13
|
+
def active_scaffold_input_record_select(column, options, ui_options: column.options)
|
14
14
|
record = options.delete(:object)
|
15
15
|
if column.association&.singular?
|
16
|
-
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
|
16
|
+
multiple = ui_options.dig(:html_options, :multiple)
|
17
|
+
html = active_scaffold_record_select(record, column, options, record.send(column.name), multiple, ui_options: ui_options)
|
18
|
+
html << active_scaffold_new_record_subform(column, record, options, ui_options: ui_options) if ui_options[:add_new]
|
19
19
|
html
|
20
20
|
elsif column.association&.collection?
|
21
|
-
active_scaffold_record_select(record, column, options, record.send(column.name), true)
|
21
|
+
active_scaffold_record_select(record, column, options, record.send(column.name), true, ui_options: ui_options)
|
22
22
|
else
|
23
|
-
active_scaffold_record_select_autocomplete(record, column, options)
|
23
|
+
active_scaffold_record_select_autocomplete(record, column, options, ui_options: ui_options)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
def active_scaffold_record_select(record, column, options, value, multiple)
|
27
|
+
def active_scaffold_record_select(record, column, options, value, multiple, ui_options: column.options)
|
28
28
|
unless column.association
|
29
29
|
raise ArgumentError, "record_select can only work against associations (and #{column.name} is not). "\
|
30
30
|
'A common mistake is to specify the foreign key field (like :user_id), instead of the association (:user).'
|
@@ -43,7 +43,7 @@ class ActiveScaffold::Bridges::RecordSelect
|
|
43
43
|
record_select_options = active_scaffold_input_text_options(options).merge(
|
44
44
|
:controller => remote_controller
|
45
45
|
)
|
46
|
-
record_select_options.merge!(
|
46
|
+
record_select_options.merge!(ui_options)
|
47
47
|
|
48
48
|
html =
|
49
49
|
if multiple
|
@@ -51,29 +51,29 @@ class ActiveScaffold::Bridges::RecordSelect
|
|
51
51
|
else
|
52
52
|
record_select_field(options[:name], value || klass.new, record_select_options)
|
53
53
|
end
|
54
|
-
html = self.class.field_error_proc
|
54
|
+
html = instance_exec(html, self, &self.class.field_error_proc) if record.errors[column.name].any?
|
55
55
|
html
|
56
56
|
end
|
57
57
|
|
58
|
-
def active_scaffold_record_select_autocomplete(record, column, options)
|
58
|
+
def active_scaffold_record_select_autocomplete(record, column, options, ui_options: column.options)
|
59
59
|
record_select_options = active_scaffold_input_text_options(options).reverse_merge(
|
60
60
|
:controller => active_scaffold_controller_for(record.class).controller_path
|
61
|
-
).merge(
|
61
|
+
).merge(ui_options)
|
62
62
|
html = record_select_autocomplete(options[:name], record, record_select_options)
|
63
|
-
html = self.class.field_error_proc
|
63
|
+
html = instance_exec(html, self, &self.class.field_error_proc) if record.errors[column.name].any?
|
64
64
|
html
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
68
|
module SearchColumnHelpers
|
69
|
-
def active_scaffold_search_record_select(column, options)
|
70
|
-
value = field_search_record_select_value(column, options[:value])
|
71
|
-
active_scaffold_record_select(options[:object], column, options, value,
|
69
|
+
def active_scaffold_search_record_select(column, options, ui_options: column.options)
|
70
|
+
value = field_search_record_select_value(column, options[:value], ui_options: ui_options)
|
71
|
+
active_scaffold_record_select(options[:object], column, options, value, ui_options[:multiple], ui_options: ui_options)
|
72
72
|
end
|
73
73
|
|
74
|
-
def field_search_record_select_value(column, value)
|
74
|
+
def field_search_record_select_value(column, value, ui_options: column.options)
|
75
75
|
return if value.blank?
|
76
|
-
if
|
76
|
+
if ui_options[:multiple]
|
77
77
|
column.association.klass.find value.collect!(&:to_i)
|
78
78
|
else
|
79
79
|
column.association.klass.find(value.to_i)
|
@@ -14,16 +14,16 @@ class ActiveScaffold::Bridges::TinyMce
|
|
14
14
|
# but not the plugins, toolbars etc.
|
15
15
|
# The other one is :tinymce_config, which selects the config to use from tinymce.yml.
|
16
16
|
# See the tinymce-rails gem documentation for usage.
|
17
|
-
def active_scaffold_input_text_editor(column, options)
|
18
|
-
options[:class] = "#{options[:class]} mceEditor #{
|
17
|
+
def active_scaffold_input_text_editor(column, options, ui_options: column.options)
|
18
|
+
options[:class] = "#{options[:class]} mceEditor #{ui_options[:class]}".strip
|
19
19
|
|
20
|
-
settings = tinymce_configuration(
|
21
|
-
|
22
|
-
|
20
|
+
settings = tinymce_configuration(ui_options[:tinymce_config] || :default).options
|
21
|
+
.reject { |k, _v| k == 'selector' }
|
22
|
+
.merge(ui_options[:tinymce] || {})
|
23
23
|
options['data-tinymce'] = settings.to_json if ActiveScaffold.js_framework != :prototype
|
24
24
|
|
25
25
|
html = []
|
26
|
-
html << send(override_input(:textarea), column, options)
|
26
|
+
html << send(override_input(:textarea), column, options, ui_options: ui_options)
|
27
27
|
if ActiveScaffold.js_framework == :prototype && (request.xhr? || params[:iframe])
|
28
28
|
html << javascript_tag("tinyMCE.settings = #{settings.to_json}; tinyMCE.execCommand('mceAddEditor', false, '#{options[:id]}');")
|
29
29
|
end
|
@@ -11,7 +11,7 @@ class ActiveScaffold::Bridges::TinyMce < ActiveScaffold::DataStructures::Bridge
|
|
11
11
|
def self.javascripts
|
12
12
|
case ActiveScaffold.js_framework
|
13
13
|
when :jquery
|
14
|
-
['tinymce
|
14
|
+
['tinymce', 'jquery/tiny_mce_bridge']
|
15
15
|
when :prototype
|
16
16
|
['tinymce', 'prototype/tiny_mce_bridge']
|
17
17
|
end
|
@@ -1,13 +1,8 @@
|
|
1
1
|
module ActiveScaffold::Bridges
|
2
2
|
class UsaStateSelect
|
3
3
|
module UsaStateSelectHelpers
|
4
|
-
def usa_state_select_options(options)
|
5
|
-
# TODO: remove when rails 3.2 support is dropped
|
6
|
-
defined?(ActionView::Helpers::InstanceTag) ? options[:object] : options
|
7
|
-
end
|
8
|
-
|
9
4
|
def usa_state_select(object, method, priority_states = nil, options = {}, html_options = {})
|
10
|
-
ActionView::Helpers::Tags::UsaStateSelect.new(object, method, self,
|
5
|
+
ActionView::Helpers::Tags::UsaStateSelect.new(object, method, self, options).to_usa_state_select_tag(priority_states, options, html_options)
|
11
6
|
end
|
12
7
|
end
|
13
8
|
|
@@ -63,18 +58,18 @@ module ActiveScaffold::Bridges
|
|
63
58
|
end
|
64
59
|
|
65
60
|
module FormColumnHelpers
|
66
|
-
def active_scaffold_input_usa_state(column, options)
|
61
|
+
def active_scaffold_input_usa_state(column, options, ui_options: column.options)
|
67
62
|
select_options = {:prompt => as_(:_select_)}
|
68
63
|
select_options.merge!(options)
|
69
|
-
options.reverse_merge!(
|
64
|
+
options.reverse_merge!(ui_options).except!(:prompt, :priority)
|
70
65
|
active_scaffold_select_name_with_multiple options
|
71
|
-
usa_state_select(:record, column.name,
|
66
|
+
usa_state_select(:record, column.name, ui_options[:priority], select_options, options.except(:object))
|
72
67
|
end
|
73
68
|
end
|
74
69
|
|
75
70
|
module SearchColumnHelpers
|
76
|
-
def active_scaffold_search_usa_state(column, options)
|
77
|
-
active_scaffold_input_usa_state(column, options.merge!(:selected => options.delete(:value)))
|
71
|
+
def active_scaffold_search_usa_state(column, options, ui_options: column.options)
|
72
|
+
active_scaffold_input_usa_state(column, options.merge!(:selected => options.delete(:value)), ui_options: ui_options)
|
78
73
|
end
|
79
74
|
end
|
80
75
|
end
|
@@ -112,7 +112,7 @@ module ActiveScaffold::Config
|
|
112
112
|
def columns=(val)
|
113
113
|
@columns._inheritable = val.collect(&:to_sym)
|
114
114
|
# Add virtual columns
|
115
|
-
@columns
|
115
|
+
@columns.add(*val)
|
116
116
|
end
|
117
117
|
|
118
118
|
# lets you override the global ActiveScaffold frontend for a specific controller
|
@@ -7,6 +7,7 @@ module ActiveScaffold::Config
|
|
7
7
|
super
|
8
8
|
@text_search = self.class.text_search
|
9
9
|
@human_conditions = self.class.human_conditions
|
10
|
+
@floating_footer = self.class.floating_footer
|
10
11
|
end
|
11
12
|
|
12
13
|
# global level configuration
|
@@ -29,6 +30,10 @@ module ActiveScaffold::Config
|
|
29
30
|
cattr_accessor :human_conditions, instance_accessor: false
|
30
31
|
@@human_conditions = false
|
31
32
|
|
33
|
+
# whether footer should float when form is too long to fit in the screen, so footer is always available while scrolling
|
34
|
+
class_attribute :floating_footer, instance_accessor: false
|
35
|
+
@@floating_footer = false
|
36
|
+
|
32
37
|
# instance-level configuration
|
33
38
|
# ----------------------------
|
34
39
|
|
@@ -71,8 +76,11 @@ module ActiveScaffold::Config
|
|
71
76
|
# instead of just filtered you may show the user a humanized search condition statment
|
72
77
|
attr_accessor :human_conditions
|
73
78
|
|
79
|
+
# whether footer should float when form is too long to fit in the screen, so footer is always available while scrolling
|
80
|
+
attr_accessor :floating_footer
|
81
|
+
|
74
82
|
UserSettings.class_eval do
|
75
|
-
user_attr :optional_columns, :group_options, :grouped_columns, :human_conditions
|
83
|
+
user_attr :optional_columns, :group_options, :grouped_columns, :human_conditions, :floating_footer
|
76
84
|
end
|
77
85
|
end
|
78
86
|
end
|
@@ -5,6 +5,7 @@ module ActiveScaffold::Config
|
|
5
5
|
@show_unauthorized_columns = self.class.show_unauthorized_columns
|
6
6
|
@refresh_list = self.class.refresh_list
|
7
7
|
@persistent = self.class.persistent
|
8
|
+
@floating_footer = self.class.floating_footer
|
8
9
|
|
9
10
|
# no global setting here because multipart should only be set for specific forms
|
10
11
|
@multipart = false
|
@@ -23,6 +24,10 @@ module ActiveScaffold::Config
|
|
23
24
|
class_attribute :refresh_list, instance_accessor: false
|
24
25
|
@@refresh_list = false
|
25
26
|
|
27
|
+
# whether footer should float when form is too long to fit in the screen, so footer is always available while scrolling
|
28
|
+
class_attribute :floating_footer, instance_accessor: false
|
29
|
+
@@floating_footer = false
|
30
|
+
|
26
31
|
# instance-level configuration
|
27
32
|
# ----------------------------
|
28
33
|
|
@@ -41,6 +46,9 @@ module ActiveScaffold::Config
|
|
41
46
|
# whether we should refresh list after create or not
|
42
47
|
attr_accessor :refresh_list
|
43
48
|
|
49
|
+
# whether footer should float when form is too long to fit in the screen, so footer is always available while scrolling
|
50
|
+
attr_accessor :floating_footer
|
51
|
+
|
44
52
|
columns_accessor :columns do
|
45
53
|
columns.exclude :created_on, :created_at, :updated_on, :updated_at, :as_marked
|
46
54
|
columns.exclude(*@core.columns.collect { |c| c.name if c.association&.polymorphic? }.compact)
|
@@ -53,7 +61,7 @@ module ActiveScaffold::Config
|
|
53
61
|
end
|
54
62
|
|
55
63
|
UserSettings.class_eval do
|
56
|
-
user_attr :persistent, :refresh_list, :show_unauthorized_columns
|
64
|
+
user_attr :persistent, :refresh_list, :show_unauthorized_columns, :floating_footer
|
57
65
|
|
58
66
|
attr_writer :multipart
|
59
67
|
def multipart?
|
@@ -11,13 +11,27 @@ module ActiveScaffold
|
|
11
11
|
@active_scaffold_constraints ||= active_scaffold_embedded_params[:constraints] || {}
|
12
12
|
end
|
13
13
|
|
14
|
+
def register_constraint?(column_name, value)
|
15
|
+
if params_hash?(value)
|
16
|
+
false
|
17
|
+
elsif value.is_a?(Array)
|
18
|
+
column = active_scaffold_config.columns[column_name]
|
19
|
+
column && value.size > (column.association&.polymorphic? ? 2 : 1)
|
20
|
+
else
|
21
|
+
true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
14
25
|
# For each enabled action, adds the constrained columns to the ActionColumns object (if it exists).
|
15
26
|
# This lets the ActionColumns object skip constrained columns.
|
16
27
|
#
|
17
|
-
# If the constraint value is a Hash, then we assume the constraint is a multi-level association constraint
|
28
|
+
# If the constraint value is a Hash, then we assume the constraint is a multi-level association constraint
|
29
|
+
# (the reverse of a has_many :through) and we do NOT register the constraint column.
|
30
|
+
# If the constraint value is an Array, or Array with more than 2 items for polymorphic column,
|
31
|
+
# we do NOT register the constraint column, as records will have different values in the column.
|
18
32
|
def register_constraints_with_action_columns(constrained_fields = nil)
|
19
33
|
constrained_fields ||= []
|
20
|
-
constrained_fields |= active_scaffold_constraints.
|
34
|
+
constrained_fields |= active_scaffold_constraints.select { |k, v| register_constraint?(k, v) }.keys.collect(&:to_sym)
|
21
35
|
exclude_actions = []
|
22
36
|
%i[list update].each do |action_name|
|
23
37
|
if active_scaffold_config.actions.include? action_name
|
@@ -111,10 +125,10 @@ module ActiveScaffold
|
|
111
125
|
value = association.klass.find(value).send(association.primary_key) if association.primary_key
|
112
126
|
|
113
127
|
if association.polymorphic?
|
114
|
-
unless value.is_a?(Array) && value.size
|
128
|
+
unless value.is_a?(Array) && value.size >= 2
|
115
129
|
raise ActiveScaffold::MalformedConstraint, polymorphic_constraint_error(association), caller
|
116
130
|
end
|
117
|
-
condition = {table => {association.foreign_type => value[0], field => value[1]}}
|
131
|
+
condition = {table => {association.foreign_type => value[0], field => value.size == 2 ? value[1] : value[1..-1]}}
|
118
132
|
else
|
119
133
|
condition = {table => {field.to_s => value}}
|
120
134
|
end
|
@@ -149,11 +163,12 @@ module ActiveScaffold
|
|
149
163
|
if column.association.collection?
|
150
164
|
record.send(k.to_s).send(:<<, column.association.klass.find(v))
|
151
165
|
elsif column.association.polymorphic?
|
152
|
-
unless v.is_a?(Array) && v.size
|
166
|
+
unless v.is_a?(Array) && v.size >= 2
|
153
167
|
raise ActiveScaffold::MalformedConstraint, polymorphic_constraint_error(column.association), caller
|
154
168
|
end
|
155
|
-
record.send("#{k}=", v[0].constantize.find(v[1]))
|
156
|
-
elsif !column.association.source_reflection&.options&.include?(:through) # regular singular association, or one-level through association
|
169
|
+
record.send("#{k}=", v[0].constantize.find(v[1])) if v.size == 2
|
170
|
+
elsif !column.association.source_reflection&.options&.include?(:through) && # regular singular association, or one-level through association
|
171
|
+
!v.is_a?(Array)
|
157
172
|
record.send("#{k}=", column.association.klass.find(v))
|
158
173
|
|
159
174
|
# setting the belongs_to side of a has_one isn't safe. if the has_one was already
|
data/lib/active_scaffold/core.rb
CHANGED
@@ -257,6 +257,8 @@ module ActiveScaffold
|
|
257
257
|
def self.column_type_cast(value, column)
|
258
258
|
if defined?(ActiveRecord) && column.is_a?(ActiveRecord::ConnectionAdapters::Column)
|
259
259
|
active_record_column_type_cast(value, column)
|
260
|
+
elsif defined?(ActiveModel) && column.is_a?(ActiveModel::Attribute)
|
261
|
+
active_record_column_type_cast(value, column.type)
|
260
262
|
elsif defined?(Mongoid) && column.is_a?(Mongoid::Fields::Standard)
|
261
263
|
mongoid_column_type_cast(value, column)
|
262
264
|
else
|
@@ -269,16 +271,10 @@ module ActiveScaffold
|
|
269
271
|
column.type.evolve value
|
270
272
|
end
|
271
273
|
|
272
|
-
def self.active_record_column_type_cast(value,
|
273
|
-
return Time.zone.at(value.to_i) if value =~ /\A\d+\z/ && %i[time datetime].include?(
|
274
|
-
|
275
|
-
|
276
|
-
elsif column.type.respond_to? :cast # jruby-jdbc and rails 5
|
277
|
-
column.type.cast value
|
278
|
-
else
|
279
|
-
cast_type = ActiveRecord::Type.lookup column.type
|
280
|
-
cast_type ? cast_type.cast(value) : value
|
281
|
-
end
|
274
|
+
def self.active_record_column_type_cast(value, column_or_type)
|
275
|
+
return Time.zone.at(value.to_i) if value =~ /\A\d+\z/ && %i[time datetime].include?(column_or_type.type)
|
276
|
+
cast_type = column_or_type.is_a?(ActiveRecord::ConnectionAdapters::Column) ? ActiveRecord::Type.lookup(column_or_type.type) : column_or_type
|
277
|
+
cast_type ? cast_type.cast(value) : value
|
282
278
|
end
|
283
279
|
end
|
284
280
|
end
|
@@ -98,31 +98,6 @@ module ActiveScaffold::DataStructures
|
|
98
98
|
visible_columns(options.reverse_merge(flatten: true)).map(&:name)
|
99
99
|
end
|
100
100
|
|
101
|
-
def each(options = nil, &proc)
|
102
|
-
if options
|
103
|
-
ActiveSupport::Deprecation.warn 'use each_column'
|
104
|
-
each_column(options, &proc)
|
105
|
-
else
|
106
|
-
super(&proc)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def collect_visible(options = {}, &proc)
|
111
|
-
ActiveSupport::Deprecation.warn "use visible_columns#{"(#{options.inspect})" if options.present?}#{'.map(&proc)' if proc}"
|
112
|
-
columns = visible_columns(options)
|
113
|
-
proc ? columns.map(&proc) : columns
|
114
|
-
end
|
115
|
-
|
116
|
-
def names
|
117
|
-
ActiveSupport::Deprecation.warn 'use visible_columns.map(&:name)'
|
118
|
-
visible_columns(flatten: true).map(&:name)
|
119
|
-
end
|
120
|
-
|
121
|
-
def names_without_auth_check
|
122
|
-
ActiveSupport::Deprecation.warn 'use to_a'
|
123
|
-
to_a
|
124
|
-
end
|
125
|
-
|
126
101
|
def action_name
|
127
102
|
@action.user_settings_key
|
128
103
|
end
|
@@ -144,7 +144,7 @@ module ActiveScaffold::DataStructures
|
|
144
144
|
end
|
145
145
|
|
146
146
|
def method_missing(name, *args, &block)
|
147
|
-
return super if name
|
147
|
+
return super if name.match?(/[!?]$/)
|
148
148
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
149
149
|
def #{name}(label = nil) # rubocop:disable Style/CommentedKeyword
|
150
150
|
@#{name} ||= subgroup('#{name}'.to_sym, label)
|
@@ -54,6 +54,14 @@ module ActiveScaffold::DataStructures::Association
|
|
54
54
|
through? && through_reflection.collection?
|
55
55
|
end
|
56
56
|
|
57
|
+
def primary_key
|
58
|
+
@association.options[:primary_key]
|
59
|
+
end
|
60
|
+
|
61
|
+
def counter_cache
|
62
|
+
@association.options[:counter_cache]
|
63
|
+
end
|
64
|
+
|
57
65
|
def polymorphic?
|
58
66
|
false
|
59
67
|
end
|
@@ -5,6 +5,14 @@ module ActiveScaffold::DataStructures::Association
|
|
5
5
|
klass.am_relations.values
|
6
6
|
end
|
7
7
|
|
8
|
+
def primary_key
|
9
|
+
@association[:primary_key]
|
10
|
+
end
|
11
|
+
|
12
|
+
def counter_cache
|
13
|
+
@association[:counter_cache]
|
14
|
+
end
|
15
|
+
|
8
16
|
def inverse_klass
|
9
17
|
as ? @association[:inverse_class_name].constantize : super
|
10
18
|
end
|
@@ -30,14 +30,6 @@ module ActiveScaffold::DataStructures::Association
|
|
30
30
|
@association.active_record
|
31
31
|
end
|
32
32
|
|
33
|
-
def primary_key
|
34
|
-
@association.options[:primary_key]
|
35
|
-
end
|
36
|
-
|
37
|
-
def counter_cache
|
38
|
-
@association.options[:counter_cache]
|
39
|
-
end
|
40
|
-
|
41
33
|
def as
|
42
34
|
@association.options[:as]
|
43
35
|
end
|
@@ -64,11 +56,7 @@ module ActiveScaffold::DataStructures::Association
|
|
64
56
|
end
|
65
57
|
|
66
58
|
def counter_cache_hack?
|
67
|
-
|
68
|
-
Rails.version < '5.0' && as
|
69
|
-
elsif belongs_to?
|
70
|
-
counter_cache && (Rails.version >= '5.0' || !polymorphic?)
|
71
|
-
end
|
59
|
+
belongs_to? && counter_cache && Rails.version < '6.0'
|
72
60
|
end
|
73
61
|
|
74
62
|
protected
|
@@ -2,15 +2,28 @@ module ActiveScaffold::DataStructures::Association
|
|
2
2
|
class Mongoid < Abstract
|
3
3
|
delegate :inverse_klass, :as, :dependent, :inverse, to: :@association
|
4
4
|
|
5
|
+
def belongs_to?
|
6
|
+
# once Ruby 2.6 support is dropped, use macro_mapping? always
|
7
|
+
defined?(::Mongoid::Association) ? macro_mapping?(:belongs_to) : super
|
8
|
+
end
|
9
|
+
|
10
|
+
def has_one? # rubocop:disable Naming/PredicateName
|
11
|
+
defined?(::Mongoid::Association) ? macro_mapping?(:has_one) : super
|
12
|
+
end
|
13
|
+
|
14
|
+
def has_many? # rubocop:disable Naming/PredicateName
|
15
|
+
defined?(::Mongoid::Association) ? macro_mapping?(:has_many) : super
|
16
|
+
end
|
17
|
+
|
18
|
+
def habtm?
|
19
|
+
defined?(::Mongoid::Association) ? macro_mapping?(:has_and_belongs_to_many) : super
|
20
|
+
end
|
21
|
+
|
5
22
|
# polymorphic belongs_to
|
6
23
|
def polymorphic?
|
7
24
|
belongs_to? && @association.polymorphic?
|
8
25
|
end
|
9
26
|
|
10
|
-
def primary_key
|
11
|
-
@association[:primary_key]
|
12
|
-
end
|
13
|
-
|
14
27
|
def association_primary_key
|
15
28
|
@association.primary_key
|
16
29
|
end
|
@@ -19,10 +32,6 @@ module ActiveScaffold::DataStructures::Association
|
|
19
32
|
@association.type
|
20
33
|
end
|
21
34
|
|
22
|
-
def counter_cache
|
23
|
-
@association[:counter_cache]
|
24
|
-
end
|
25
|
-
|
26
35
|
def table_name
|
27
36
|
@association.klass.collection.name
|
28
37
|
end
|
@@ -38,5 +47,9 @@ module ActiveScaffold::DataStructures::Association
|
|
38
47
|
def self.reflect_on_all_associations(klass)
|
39
48
|
klass.relations.values
|
40
49
|
end
|
50
|
+
|
51
|
+
def macro_mapping?(macro)
|
52
|
+
@association.is_a? ::Mongoid::Association::MACRO_MAPPING[macro]
|
53
|
+
end
|
41
54
|
end
|
42
55
|
end
|