active_scaffold 3.5.4 → 3.6.0
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 → CHANGELOG.rdoc} +72 -0
- data/README.md +20 -8
- data/app/assets/javascripts/active_scaffold.js.erb +0 -1
- data/app/assets/javascripts/jquery/active_scaffold.js +98 -7
- data/app/assets/stylesheets/active_scaffold_colors.scss +1 -1
- data/app/assets/stylesheets/active_scaffold_layout.css +52 -29
- data/app/views/active_scaffold_overrides/_base_form.html.erb +2 -2
- data/app/views/active_scaffold_overrides/_form.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_form_association.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +3 -2
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +9 -7
- data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +4 -4
- data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_list.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_list_header.html.erb +5 -7
- data/app/views/active_scaffold_overrides/_list_messages.html.erb +1 -0
- data/app/views/active_scaffold_overrides/_list_record.html.erb +4 -5
- data/app/views/active_scaffold_overrides/_list_with_header.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_messages.html.erb +1 -0
- data/app/views/active_scaffold_overrides/_refresh_list.js.erb +4 -0
- data/app/views/active_scaffold_overrides/_render_field.js.erb +2 -1
- data/app/views/active_scaffold_overrides/_show_association_horizontal.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_show_columns.html.erb +2 -2
- data/app/views/active_scaffold_overrides/_show_horizontal_record.html.erb +4 -4
- data/app/views/active_scaffold_overrides/_update_calculations.js.erb +1 -1
- data/app/views/active_scaffold_overrides/_update_column.js.erb +2 -2
- data/app/views/active_scaffold_overrides/_vertical_subform.html.erb +2 -2
- data/app/views/active_scaffold_overrides/action_confirmation.html.erb +2 -2
- data/app/views/active_scaffold_overrides/delete.html.erb +2 -2
- data/app/views/active_scaffold_overrides/on_action_update.js.erb +16 -6
- data/app/views/active_scaffold_overrides/on_update.js.erb +1 -1
- data/app/views/active_scaffold_overrides/row.js.erb +1 -1
- data/app/views/active_scaffold_overrides/update_column.js.erb +2 -2
- data/config/locales/de.yml +2 -1
- data/config/locales/en.yml +1 -0
- data/config/locales/es.yml +1 -0
- data/config/locales/fr.yml +2 -1
- data/config/locales/hu.yml +1 -0
- data/config/locales/ja.yml +1 -0
- data/config/locales/ru.yml +1 -0
- data/lib/active_scaffold.rb +19 -16
- data/lib/active_scaffold/actions/common_search.rb +11 -8
- data/lib/active_scaffold/actions/core.rb +91 -70
- data/lib/active_scaffold/actions/create.rb +28 -28
- data/lib/active_scaffold/actions/delete.rb +3 -3
- data/lib/active_scaffold/actions/field_search.rb +53 -43
- data/lib/active_scaffold/actions/list.rb +111 -27
- data/lib/active_scaffold/actions/nested.rb +65 -48
- data/lib/active_scaffold/actions/search.rb +1 -1
- data/lib/active_scaffold/actions/show.rb +4 -4
- data/lib/active_scaffold/actions/subform.rb +23 -22
- data/lib/active_scaffold/actions/update.rb +96 -77
- data/lib/active_scaffold/active_record_permissions.rb +2 -11
- data/lib/active_scaffold/attribute_params.rb +102 -94
- data/lib/active_scaffold/bridges.rb +8 -8
- data/lib/active_scaffold/bridges/active_storage.rb +6 -0
- data/lib/active_scaffold/bridges/active_storage/active_storage_bridge.rb +34 -0
- data/lib/active_scaffold/bridges/active_storage/active_storage_helpers.rb +54 -0
- data/lib/active_scaffold/bridges/active_storage/form_ui.rb +22 -0
- data/lib/active_scaffold/bridges/active_storage/list_ui.rb +36 -0
- data/lib/active_scaffold/bridges/bitfields.rb +2 -1
- data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +12 -15
- data/lib/active_scaffold/bridges/bitfields/list_ui.rb +19 -0
- data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +1 -1
- data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +9 -12
- data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +1 -1
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +2 -2
- data/lib/active_scaffold/bridges/chosen/helpers.rb +7 -6
- data/lib/active_scaffold/bridges/date_picker/ext.rb +0 -13
- data/lib/active_scaffold/bridges/date_picker/helper.rb +49 -44
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +3 -3
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +3 -3
- data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +10 -7
- data/lib/active_scaffold/bridges/paper_trail.rb +1 -1
- data/lib/active_scaffold/bridges/paper_trail/actions.rb +3 -1
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +2 -2
- data/lib/active_scaffold/bridges/record_select/helpers.rb +15 -17
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +20 -19
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +3 -1
- data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +21 -4
- data/lib/active_scaffold/config/base.rb +133 -41
- data/lib/active_scaffold/config/core.rb +146 -18
- data/lib/active_scaffold/config/delete.rb +14 -1
- data/lib/active_scaffold/config/field_search.rb +7 -1
- data/lib/active_scaffold/config/form.rb +10 -1
- data/lib/active_scaffold/config/list.rb +39 -13
- data/lib/active_scaffold/config/mark.rb +4 -2
- data/lib/active_scaffold/config/nested.rb +16 -17
- data/lib/active_scaffold/config/search.rb +9 -0
- data/lib/active_scaffold/config/show.rb +4 -0
- data/lib/active_scaffold/config/update.rb +4 -0
- data/lib/active_scaffold/configurable.rb +14 -7
- data/lib/active_scaffold/constraints.rb +22 -20
- data/lib/active_scaffold/core.rb +67 -28
- data/lib/active_scaffold/data_structures/action_columns.rb +50 -59
- data/lib/active_scaffold/data_structures/action_link.rb +50 -20
- data/lib/active_scaffold/data_structures/action_links.rb +15 -13
- data/lib/active_scaffold/data_structures/association/abstract.rb +38 -15
- data/lib/active_scaffold/data_structures/association/active_mongoid.rb +2 -6
- data/lib/active_scaffold/data_structures/association/active_record.rb +6 -2
- data/lib/active_scaffold/data_structures/association/mongoid.rb +0 -3
- data/lib/active_scaffold/data_structures/column.rb +75 -66
- data/lib/active_scaffold/data_structures/columns.rb +3 -2
- data/lib/active_scaffold/data_structures/nested_info.rb +33 -19
- data/lib/active_scaffold/data_structures/set.rb +8 -0
- data/lib/active_scaffold/data_structures/sorting.rb +10 -2
- data/lib/active_scaffold/delayed_setup.rb +16 -5
- data/lib/active_scaffold/extensions/action_controller_rendering.rb +3 -2
- data/lib/active_scaffold/extensions/action_view_rendering.rb +93 -32
- data/lib/active_scaffold/extensions/cow_proxy.rb +95 -0
- data/lib/active_scaffold/extensions/ice_nine.rb +36 -0
- data/lib/active_scaffold/extensions/left_outer_joins.rb +8 -33
- data/lib/active_scaffold/extensions/localize.rb +3 -1
- data/lib/active_scaffold/extensions/routing_mapper.rb +6 -45
- data/lib/active_scaffold/extensions/to_label.rb +3 -2
- data/lib/active_scaffold/extensions/unsaved_record.rb +2 -4
- data/lib/active_scaffold/finder.rb +110 -77
- data/lib/active_scaffold/helpers/action_link_helpers.rb +62 -36
- data/lib/active_scaffold/helpers/association_helpers.rb +18 -16
- data/lib/active_scaffold/helpers/controller_helpers.rb +34 -10
- data/lib/active_scaffold/helpers/form_column_helpers.rb +196 -124
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +1 -1
- data/lib/active_scaffold/helpers/id_helpers.rb +6 -2
- data/lib/active_scaffold/helpers/list_column_helpers.rb +90 -57
- data/lib/active_scaffold/helpers/pagination_helpers.rb +2 -2
- data/lib/active_scaffold/helpers/search_column_helpers.rb +29 -34
- data/lib/active_scaffold/helpers/show_column_helpers.rb +3 -5
- data/lib/active_scaffold/helpers/view_helpers.rb +39 -36
- data/lib/active_scaffold/marked_model.rb +2 -2
- data/lib/active_scaffold/orm_checks.rb +3 -7
- data/lib/active_scaffold/paginator.rb +7 -7
- data/lib/active_scaffold/registry.rb +33 -0
- data/lib/active_scaffold/responds_to_parent.rb +8 -11
- data/lib/active_scaffold/tableless.rb +82 -66
- data/lib/active_scaffold/version.rb +2 -2
- data/lib/generators/active_scaffold/controller_generator.rb +2 -2
- data/lib/generators/active_scaffold/install_generator.rb +52 -4
- data/lib/generators/active_scaffold/resource_generator.rb +2 -2
- data/shoulda_macros/macros.rb +3 -1
- data/test/bridges/date_picker_test.rb +1 -2
- data/test/bridges/paperclip_test.rb +6 -6
- data/test/class_with_finder.rb +2 -2
- data/test/company.rb +4 -4
- data/test/config/create_test.rb +4 -2
- data/test/config/nested_test.rb +1 -1
- data/test/config/show_test.rb +1 -1
- data/test/config/update_test.rb +7 -6
- data/test/data_structures/action_columns_test.rb +2 -2
- data/test/data_structures/action_links_test.rb +1 -1
- data/test/data_structures/column_test.rb +3 -6
- data/test/data_structures/columns_test.rb +2 -2
- data/test/data_structures/sorting_test.rb +7 -0
- data/test/extensions/action_view_rendering_test.rb +20 -0
- data/test/extensions/active_record_test.rb +4 -4
- data/test/extensions/routing_mapper_test.rb +2 -2
- data/test/helpers/list_column_helpers_test.rb +3 -1
- data/test/misc/active_record_permissions_test.rb +3 -11
- data/test/misc/attribute_params_test.rb +12 -8
- data/test/misc/calculation_test.rb +1 -1
- data/test/misc/configurable_test.rb +10 -10
- data/test/misc/constraints_test.rb +2 -2
- data/test/misc/convert_numbers_format_test.rb +7 -3
- data/test/misc/lang_test.rb +1 -1
- data/test/misc/parse_datetime_test.rb +3 -4
- data/test/misc/tableless_test.rb +14 -0
- data/test/mock_app/Rakefile +1 -1
- data/test/mock_app/app/assets/config/manifest.js +0 -0
- data/test/mock_app/app/controllers/cars_controller.rb +1 -0
- data/test/mock_app/app/controllers/people_controller.rb +5 -1
- 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/mock_app/config/application.rb +2 -1
- data/test/mock_app/config/boot.rb +1 -1
- data/test/mock_app/config/environment.rb +2 -2
- data/test/mock_app/config/routes.rb +4 -1
- data/test/mock_app/db/schema.rb +2 -0
- data/test/performance/list_cars_performance_test.rb +34 -0
- data/test/performance/list_people_performance_test.rb +31 -0
- data/test/performance_test_help.rb +3 -0
- data/test/test_helper.rb +12 -4
- metadata +69 -18
- data/app/assets/javascripts/prototype/rico_corner.js +0 -370
- data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +0 -7
@@ -23,6 +23,7 @@ module ActiveScaffold::DataStructures
|
|
23
23
|
@active_record_class = active_record_class
|
24
24
|
@_inheritable = []
|
25
25
|
@set = []
|
26
|
+
@sorted = nil
|
26
27
|
|
27
28
|
add(*args)
|
28
29
|
end
|
@@ -48,8 +49,8 @@ module ActiveScaffold::DataStructures
|
|
48
49
|
column = self[association]
|
49
50
|
raise ArgumentError, "unknown column #{association}" if column.nil?
|
50
51
|
raise ArgumentError, "column #{association} is not an association" if column.association.nil?
|
51
|
-
raise
|
52
|
-
raise
|
52
|
+
raise ArgumentError, "column #{association} is not singular association" unless column.association.singular?
|
53
|
+
raise ArgumentError, "column #{association} is polymorphic association" if column.association.polymorphic?
|
53
54
|
|
54
55
|
klass = column.association.klass
|
55
56
|
columns.each do |col|
|
@@ -31,7 +31,7 @@ module ActiveScaffold::DataStructures
|
|
31
31
|
false
|
32
32
|
end
|
33
33
|
|
34
|
-
def has_many?
|
34
|
+
def has_many? # rubocop:disable Naming/PredicateName
|
35
35
|
false
|
36
36
|
end
|
37
37
|
|
@@ -39,7 +39,7 @@ module ActiveScaffold::DataStructures
|
|
39
39
|
false
|
40
40
|
end
|
41
41
|
|
42
|
-
def has_one?
|
42
|
+
def has_one? # rubocop:disable Naming/PredicateName
|
43
43
|
false
|
44
44
|
end
|
45
45
|
|
@@ -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
|
@@ -74,7 +78,7 @@ module ActiveScaffold::DataStructures
|
|
74
78
|
column = parent_scaffold.active_scaffold_config.columns[params[:association].to_sym]
|
75
79
|
@param_name = column.model.name.foreign_key.to_sym
|
76
80
|
@parent_id = params[@param_name]
|
77
|
-
@association = column
|
81
|
+
@association = column&.association
|
78
82
|
@child_association = association.reverse_association(model) if association
|
79
83
|
setup_constrained_fields
|
80
84
|
end
|
@@ -83,46 +87,56 @@ module ActiveScaffold::DataStructures
|
|
83
87
|
|
84
88
|
# A through association with has_one or has_many as source association
|
85
89
|
# create cannot be called in nested through associations, and not-nested through associations
|
86
|
-
# unless create columns include through reflection of reverse association
|
90
|
+
# unless is through singular or create columns include through reflection of reverse association
|
87
91
|
# e.g. customer -> networks -> firewall, reverse is firewall -> network -> customer,
|
88
92
|
# firewall can be created if create columns include network
|
89
93
|
def readonly_through_association?(columns)
|
90
94
|
return false unless through_association?
|
91
|
-
return true if association.through_reflection.options[:through]
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
+
return true if association.through_reflection.options[:through] # create not possible, too many levels
|
96
|
+
return true if association.source_reflection.options[:through] # create not possible, too many levels
|
97
|
+
return false if association.through_singular? # create allowed, AS has code for this
|
98
|
+
|
99
|
+
# create allowed only if through reflection in record to be created is included in create columns
|
100
|
+
!child_association || !columns.include?(child_association.through_reflection.name)
|
95
101
|
end
|
96
102
|
|
97
103
|
def through_association?
|
98
104
|
association.through?
|
99
105
|
end
|
100
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
|
+
|
101
115
|
def sorted?(chain)
|
102
116
|
default_sorting(chain).present?
|
103
117
|
end
|
104
118
|
|
105
119
|
def default_sorting(chain)
|
106
120
|
return @default_sorting if defined? @default_sorting
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
end
|
121
|
+
return unless association.scope.is_a?(Proc) && chain.respond_to?(:values) && chain.values[:order]
|
122
|
+
@default_sorting = chain.values[:order]
|
123
|
+
@default_sorting = @default_sorting.map(&:to_sql) if @default_sorting[0].is_a? Arel::Nodes::Node
|
124
|
+
@default_sorting = @default_sorting.join(', ')
|
112
125
|
end
|
113
126
|
|
114
127
|
def to_params
|
115
|
-
super.merge(:association => @association.name,
|
128
|
+
super.merge(:association => @association.name, @param_name => parent_id)
|
116
129
|
end
|
117
130
|
|
118
131
|
protected
|
119
132
|
|
120
133
|
def setup_constrained_fields
|
121
|
-
@constrained_fields =
|
122
|
-
@constrained_fields
|
123
|
-
|
124
|
-
|
125
|
-
|
134
|
+
@constrained_fields = Array(association.foreign_key).map(&:to_sym) unless association.belongs_to?
|
135
|
+
@constrained_fields ||= []
|
136
|
+
return unless child_association && child_association != association
|
137
|
+
|
138
|
+
@constrained_fields << child_association.name
|
139
|
+
@constrained_fields << child_association.foreign_type.to_sym if child_association.polymorphic?
|
126
140
|
end
|
127
141
|
end
|
128
142
|
|
@@ -7,6 +7,10 @@ module ActiveScaffold::DataStructures
|
|
7
7
|
set_values(*args)
|
8
8
|
end
|
9
9
|
|
10
|
+
def initialize_dup(other)
|
11
|
+
@set = other.set.dup
|
12
|
+
end
|
13
|
+
|
10
14
|
def set_values(*args)
|
11
15
|
@set = []
|
12
16
|
add(*args)
|
@@ -56,5 +60,9 @@ module ActiveScaffold::DataStructures
|
|
56
60
|
def empty?
|
57
61
|
@set.empty?
|
58
62
|
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
attr_reader :set
|
59
67
|
end
|
60
68
|
end
|
@@ -14,6 +14,7 @@ module ActiveScaffold::DataStructures
|
|
14
14
|
@clauses = []
|
15
15
|
@constraint_columns = []
|
16
16
|
@model = model
|
17
|
+
@sorting_by_primary_key = false
|
17
18
|
end
|
18
19
|
|
19
20
|
def set_default_sorting
|
@@ -55,6 +56,9 @@ module ActiveScaffold::DataStructures
|
|
55
56
|
# set({column => direction}, {column => direction})
|
56
57
|
# set([column, direction], [column, direction])
|
57
58
|
def set(*args)
|
59
|
+
# TODO: add deprecation unless args.size == 1 && args[0].is_a? Hash
|
60
|
+
# when deprecation is removed:
|
61
|
+
# * change list#sorting= to sorting.set(val)
|
58
62
|
clear
|
59
63
|
if args.first.is_a?(Enumerable)
|
60
64
|
args.each do |h|
|
@@ -103,6 +107,10 @@ module ActiveScaffold::DataStructures
|
|
103
107
|
@clauses.each { |clause| yield clause }
|
104
108
|
end
|
105
109
|
|
110
|
+
def each_column
|
111
|
+
@clauses.each { |clause| yield clause[0] }
|
112
|
+
end
|
113
|
+
|
106
114
|
# provides quick access to the first (and sometimes only) clause
|
107
115
|
def first
|
108
116
|
@clauses.first
|
@@ -120,7 +128,7 @@ module ActiveScaffold::DataStructures
|
|
120
128
|
order = []
|
121
129
|
each do |sort_column, sort_direction|
|
122
130
|
next if constraint_columns.include? sort_column.name
|
123
|
-
sql = grouped_columns_calculations
|
131
|
+
sql = grouped_columns_calculations&.dig(sort_column.name) || sort_column.sort[:sql]
|
124
132
|
next if sql.blank?
|
125
133
|
sql = sql.to_sql if sql.respond_to?(:to_sql)
|
126
134
|
|
@@ -200,7 +208,7 @@ module ActiveScaffold::DataStructures
|
|
200
208
|
end
|
201
209
|
|
202
210
|
def postgres?
|
203
|
-
model.connection
|
211
|
+
model.connection&.adapter_name == 'PostgreSQL'
|
204
212
|
end
|
205
213
|
|
206
214
|
def setup_primary_key_order_clause
|
@@ -11,14 +11,25 @@ module ActiveScaffold
|
|
11
11
|
|
12
12
|
module ClassMethods
|
13
13
|
def active_scaffold(model_id = nil, &block)
|
14
|
-
@
|
14
|
+
@delayed_monitor ||= Monitor.new
|
15
|
+
@active_scaffold_delayed = proc do
|
16
|
+
begin
|
17
|
+
@_prefixes = nil # clean prefixes in case is already cached, so our local_prefixes override is picked up
|
18
|
+
super(model_id, &block)
|
19
|
+
@active_scaffold_delayed = @delayed_monitor = nil # after configuring, no need to keep proc or monitor
|
20
|
+
rescue StandardError
|
21
|
+
# clear config variable if failed, so next request tries again
|
22
|
+
@active_scaffold_config = nil
|
23
|
+
raise
|
24
|
+
end
|
25
|
+
end
|
15
26
|
end
|
16
27
|
|
17
28
|
def config_active_scaffold_delayed
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
29
|
+
@delayed_monitor&.synchronize do
|
30
|
+
# if called in same thread while running config, do nothing
|
31
|
+
@active_scaffold_delayed&.call unless @active_scaffold_config
|
32
|
+
end
|
22
33
|
end
|
23
34
|
|
24
35
|
def active_scaffold_config
|
@@ -5,9 +5,10 @@ module ActiveScaffold
|
|
5
5
|
if self.class.uses_active_scaffold? && params[:adapter] && @rendering_adapter.nil? && request.xhr?
|
6
6
|
@rendering_adapter = true # recursion control
|
7
7
|
# if we need an adapter, then we render the actual stuff to a string and insert it into the adapter template
|
8
|
-
opts = args.
|
8
|
+
opts = args.any? ? args.first : {}
|
9
|
+
|
9
10
|
render :partial => params[:adapter][1..-1],
|
10
|
-
:locals => {:payload => render_to_string(opts.merge(:layout => false), &block).html_safe},
|
11
|
+
:locals => {:payload => render_to_string(opts.merge(:layout => false), &block).html_safe}, # rubocop:disable Rails/OutputSafety
|
11
12
|
:use_full_path => true, :layout => false, :content_type => :html
|
12
13
|
@rendering_adapter = nil # recursion control
|
13
14
|
else
|
@@ -39,41 +39,33 @@ module ActiveScaffold #:nodoc:
|
|
39
39
|
if args.first.is_a?(Hash) && args.first[:active_scaffold]
|
40
40
|
render_embedded args.first
|
41
41
|
elsif args.first == :super
|
42
|
-
@
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
options = args[1] || {}
|
49
|
-
options[:locals] ||= {}
|
50
|
-
if view_stack.last
|
51
|
-
options[:locals] = view_stack.last[:locals].merge!(options[:locals]) if view_stack.last[:locals]
|
52
|
-
options[:object] ||= view_stack.last[:object] if view_stack.last[:object]
|
53
|
-
end
|
54
|
-
options[:template] = template
|
55
|
-
# if prefix is active_scaffold_overrides we must try to render with this prefix in following paths
|
56
|
-
if prefix != 'active_scaffold_overrides'
|
57
|
-
options[:prefixes] = lookup_context.prefixes.drop((lookup_context.prefixes.find_index(prefix) || -1) + 1)
|
58
|
-
else
|
59
|
-
options[:prefixes] = ['active_scaffold_overrides']
|
60
|
-
last_view_path = File.expand_path(File.dirname(File.dirname(lookup_context.last_template.inspect)), Rails.root)
|
61
|
-
lookup_context.view_paths = view_paths.drop(view_paths.find_index { |path| path.to_s == last_view_path } + 1)
|
42
|
+
if @lookup_context # rails 6
|
43
|
+
@_lookup_context ||= lookup_context
|
44
|
+
else # rails < 6
|
45
|
+
@_view_paths ||= lookup_context.view_paths.clone
|
46
|
+
@_last_template ||= lookup_context.last_template
|
62
47
|
end
|
63
|
-
result = super
|
64
|
-
lookup_context
|
65
|
-
lookup_context.
|
48
|
+
result = super options_for_render_super(args[1])
|
49
|
+
@lookup_context = @_lookup_context if @_lookup_context # rails 6
|
50
|
+
lookup_context.view_paths = @_view_paths if @_view_paths # rails < 6
|
51
|
+
lookup_context.last_template = @_last_template if @_last_template # rails < 6
|
66
52
|
result
|
67
53
|
else
|
68
|
-
@
|
54
|
+
if @lookup_context # rails 6
|
55
|
+
@_lookup_context ||= lookup_context
|
56
|
+
else # rails < 6
|
57
|
+
@_view_paths ||= lookup_context.view_paths.clone
|
58
|
+
end
|
69
59
|
last_template = lookup_context.last_template
|
70
|
-
current_view =
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
60
|
+
current_view =
|
61
|
+
if args[0].is_a?(Hash)
|
62
|
+
{locals: args[0][:locals], object: args[0][:object]}
|
63
|
+
else # call is render 'partial', locals_hash
|
64
|
+
{locals: args[1]}
|
65
|
+
end
|
75
66
|
view_stack << current_view if current_view
|
76
|
-
lookup_context
|
67
|
+
@lookup_context = @_lookup_context if @_lookup_context # rails 6, reset lookup_context in case a view render :super, and then render :partial
|
68
|
+
lookup_context.view_paths = @_view_paths if @_view_paths # rails < 6, reset view_paths in case a view render :super, and then render :partial
|
77
69
|
result = super
|
78
70
|
view_stack.pop if current_view.present?
|
79
71
|
lookup_context.last_template = last_template
|
@@ -87,6 +79,46 @@ module ActiveScaffold #:nodoc:
|
|
87
79
|
|
88
80
|
private
|
89
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
|
+
|
90
122
|
def render_embedded(options)
|
91
123
|
require 'digest/md5'
|
92
124
|
|
@@ -114,9 +146,13 @@ module ActiveScaffold #:nodoc:
|
|
114
146
|
content_tag(:div, :id => id, :class => 'active-scaffold-component', :data => {:refresh => url}) do
|
115
147
|
# parse the ActiveRecord model name from the controller path, which
|
116
148
|
# might be a namespaced controller (e.g., 'admin/admins')
|
117
|
-
model = remote_controller.to_s.sub(
|
149
|
+
model = remote_controller.to_s.sub(%r{.*/}, '').singularize
|
118
150
|
content_tag(:div, :class => 'active-scaffold-header') do
|
119
|
-
content_tag
|
151
|
+
content_tag(:h2) do
|
152
|
+
link_label = options[:label] || active_scaffold_config_for(model).list.label
|
153
|
+
link_to(link_label, url, remote: true, class: 'load-embedded', data: {error_msg: as_(:error_500)}) <<
|
154
|
+
loading_indicator_tag(url_options)
|
155
|
+
end
|
120
156
|
end
|
121
157
|
end
|
122
158
|
end
|
@@ -133,5 +169,30 @@ module ActionView
|
|
133
169
|
Base.class_eval do
|
134
170
|
include ActiveScaffold::RenderingHelper
|
135
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
|
136
197
|
end
|
137
198
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'cow_proxy'
|
2
|
+
|
3
|
+
module CowProxy
|
4
|
+
module ActiveScaffold
|
5
|
+
module DataStructures
|
6
|
+
class Column < ::CowProxy::WrapClass(::ActiveScaffold::DataStructures::Column)
|
7
|
+
# readonly and called many times in list action
|
8
|
+
delegate :name, :cache_key, :delegated_association, :association, to: :__getobj__
|
9
|
+
|
10
|
+
def link
|
11
|
+
return @link if defined?(@link)
|
12
|
+
if __getobj__.frozen?
|
13
|
+
link_var = __getobj__.instance_variable_get(:@link)
|
14
|
+
if link_var.is_a?(Proc)
|
15
|
+
@link = link_var.call self
|
16
|
+
return @link
|
17
|
+
end
|
18
|
+
end
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def sort_by(options)
|
23
|
+
@sort = options
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Set < ::CowProxy::WrapClass(::ActiveScaffold::DataStructures::Set)
|
28
|
+
protected
|
29
|
+
|
30
|
+
# Copy wrapped values to duplicated wrapped object
|
31
|
+
# @see CowProxy::Base#__copy_on_write__
|
32
|
+
# @return duplicated wrapped object
|
33
|
+
def __copy_on_write__(*)
|
34
|
+
super.tap do
|
35
|
+
new_set = __getobj__.instance_variable_get(:@set).dup
|
36
|
+
__getobj__.instance_variable_set(:@set, new_set)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class ActionColumns < ::CowProxy::WrapClass(::ActiveScaffold::DataStructures::ActionColumns)
|
42
|
+
def each_column(options = {})
|
43
|
+
__getobj__.each_column(options.reverse_merge(core_columns: action.core.columns)) do |column|
|
44
|
+
if column.is_a?(::ActiveScaffold::DataStructures::ActionColumns)
|
45
|
+
yield ::CowProxy.wrap(column).tap { |group| group.action = action }
|
46
|
+
else
|
47
|
+
yield column
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class ActionLinks < ::CowProxy::WrapClass(::ActiveScaffold::DataStructures::ActionLinks)
|
54
|
+
def method_missing(name, *args, &block)
|
55
|
+
CowProxy.debug { "method missing #{name} in #{__getobj__.name}" }
|
56
|
+
return super if name =~ /[!?]$/
|
57
|
+
subgroup =
|
58
|
+
if _instance_variable_defined?("@#{name}")
|
59
|
+
_instance_variable_get("@#{name}")
|
60
|
+
else
|
61
|
+
__copy_on_write__ if __getobj__.frozen?
|
62
|
+
group = __getobj__.subgroup(name, args.first)
|
63
|
+
if group.frozen?
|
64
|
+
group = __wrap__(group)
|
65
|
+
else
|
66
|
+
CowProxy.debug { "created subgroup #{group.name}" }
|
67
|
+
end
|
68
|
+
_instance_variable_set("@#{name}", group)
|
69
|
+
end
|
70
|
+
yield subgroup if block
|
71
|
+
subgroup
|
72
|
+
end
|
73
|
+
|
74
|
+
def respond_to_missing?(name, *)
|
75
|
+
name !~ /[!?]$/
|
76
|
+
end
|
77
|
+
|
78
|
+
protected
|
79
|
+
|
80
|
+
# Copy wrapped values to duplicated wrapped object
|
81
|
+
# @see CowProxy::Base#__copy_on_write__
|
82
|
+
# @return duplicated wrapped object
|
83
|
+
def __copy_on_write__(*)
|
84
|
+
index = @parent_proxy.instance_variable_get(:@set).index(__getobj__) if @parent_proxy
|
85
|
+
super.tap do
|
86
|
+
CowProxy.debug { "replace #{index} with proxy obj in parent #{@parent_proxy.name}" } if index
|
87
|
+
@parent_proxy.instance_variable_get(:@set)[index] = self if index
|
88
|
+
new_set = __getobj__.instance_variable_get(:@set).dup
|
89
|
+
__getobj__.instance_variable_set(:@set, new_set)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|