active_scaffold 4.1.6 → 4.2.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.rdoc +27 -0
- data/README.md +6 -5
- data/app/assets/javascripts/jquery/active_scaffold.js +98 -47
- data/app/assets/javascripts/jquery/tiny_mce_bridge.js +15 -2
- data/app/assets/stylesheets/active_scaffold_images.scss +6 -0
- data/app/assets/stylesheets/{active_scaffold_layout.css → active_scaffold_layout.scss} +104 -4
- data/app/assets/stylesheets/tiny_mce_bridge.scss +11 -0
- data/app/views/active_scaffold_overrides/_base_form.html.erb +3 -2
- data/app/views/active_scaffold_overrides/_field_search.html.erb +2 -2
- data/app/views/active_scaffold_overrides/_form.html.erb +14 -4
- data/app/views/active_scaffold_overrides/_form_association.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +5 -11
- data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +1 -3
- data/app/views/active_scaffold_overrides/_new_record.js.erb +3 -1
- data/app/views/active_scaffold_overrides/_refresh_list.js.erb +1 -1
- data/app/views/active_scaffold_overrides/_render_field.js.erb +67 -36
- data/app/views/active_scaffold_overrides/_update_field_on_create.js.erb +41 -6
- data/app/views/active_scaffold_overrides/action_links_menu.js.erb +1 -0
- data/config/locales/de.yml +9 -0
- data/config/locales/en.yml +11 -0
- data/config/locales/es.yml +8 -0
- data/config/locales/fr.yml +8 -0
- data/config/locales/hu.yml +8 -0
- data/config/locales/ja.yml +8 -0
- data/config/locales/ru.yml +8 -0
- data/lib/active_scaffold/actions/common_search.rb +2 -0
- data/lib/active_scaffold/actions/core.rb +47 -23
- data/lib/active_scaffold/actions/create.rb +2 -0
- data/lib/active_scaffold/actions/delete.rb +6 -0
- data/lib/active_scaffold/actions/field_search.rb +36 -11
- data/lib/active_scaffold/actions/list.rb +26 -8
- data/lib/active_scaffold/actions/mark.rb +6 -0
- data/lib/active_scaffold/actions/nested.rb +2 -0
- data/lib/active_scaffold/actions/search.rb +7 -0
- data/lib/active_scaffold/actions/show.rb +6 -0
- data/lib/active_scaffold/actions/subform.rb +2 -0
- data/lib/active_scaffold/actions/update.rb +8 -1
- data/lib/active_scaffold/active_record_permissions.rb +3 -3
- data/lib/active_scaffold/attribute_params.rb +35 -17
- data/lib/active_scaffold/bridges/active_storage/active_storage_bridge.rb +2 -0
- data/lib/active_scaffold/bridges/active_storage/active_storage_helpers.rb +10 -9
- data/lib/active_scaffold/bridges/active_storage/form_ui.rb +10 -3
- data/lib/active_scaffold/bridges/active_storage/list_ui.rb +2 -0
- data/lib/active_scaffold/bridges/active_storage.rb +2 -0
- data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +2 -0
- data/lib/active_scaffold/bridges/ancestry.rb +2 -0
- data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +2 -0
- data/lib/active_scaffold/bridges/bitfields/list_ui.rb +2 -0
- data/lib/active_scaffold/bridges/bitfields.rb +2 -0
- data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +9 -6
- data/lib/active_scaffold/bridges/cancan.rb +2 -0
- data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +2 -0
- data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge_helpers.rb +2 -0
- data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +3 -1
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +2 -0
- data/lib/active_scaffold/bridges/carrierwave.rb +2 -0
- data/lib/active_scaffold/bridges/chosen/helpers.rb +13 -4
- data/lib/active_scaffold/bridges/chosen.rb +2 -0
- data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +2 -0
- data/lib/active_scaffold/bridges/country_select.rb +2 -0
- data/lib/active_scaffold/bridges/date_picker/ext.rb +6 -0
- data/lib/active_scaffold/bridges/date_picker/helper.rb +7 -3
- data/lib/active_scaffold/bridges/date_picker.rb +2 -0
- data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +2 -0
- data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge_helpers.rb +2 -0
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -1
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +2 -0
- data/lib/active_scaffold/bridges/dragonfly.rb +2 -0
- data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +2 -0
- data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +10 -9
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +2 -0
- data/lib/active_scaffold/bridges/file_column/list_ui.rb +2 -0
- data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +2 -0
- data/lib/active_scaffold/bridges/file_column/test/mock_model.rb +2 -0
- data/lib/active_scaffold/bridges/file_column.rb +2 -0
- data/lib/active_scaffold/bridges/logical_query_parser/tokens_grammar.rb +65 -0
- data/lib/active_scaffold/bridges/logical_query_parser/tokens_grammar.treetop +31 -0
- data/lib/active_scaffold/bridges/logical_query_parser.rb +9 -0
- data/lib/active_scaffold/bridges/paper_trail/actions.rb +2 -0
- data/lib/active_scaffold/bridges/paper_trail/config.rb +2 -0
- data/lib/active_scaffold/bridges/paper_trail/helper.rb +2 -0
- data/lib/active_scaffold/bridges/paper_trail/paper_trail_bridge.rb +2 -0
- data/lib/active_scaffold/bridges/paper_trail.rb +2 -0
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -1
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +2 -0
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +2 -0
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +12 -12
- data/lib/active_scaffold/bridges/paperclip.rb +2 -0
- data/lib/active_scaffold/bridges/record_select/helpers.rb +19 -11
- data/lib/active_scaffold/bridges/record_select.rb +2 -0
- data/lib/active_scaffold/bridges/semantic_attributes/column.rb +2 -0
- data/lib/active_scaffold/bridges/semantic_attributes.rb +2 -0
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +3 -1
- data/lib/active_scaffold/bridges/tiny_mce.rb +6 -0
- data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +2 -0
- data/lib/active_scaffold/bridges/usa_state_select.rb +2 -0
- data/lib/active_scaffold/bridges.rb +2 -0
- data/lib/active_scaffold/config/base.rb +12 -7
- data/lib/active_scaffold/config/core.rb +26 -23
- data/lib/active_scaffold/config/create.rb +2 -0
- data/lib/active_scaffold/config/delete.rb +2 -0
- data/lib/active_scaffold/config/field_search.rb +2 -0
- data/lib/active_scaffold/config/form.rb +11 -1
- data/lib/active_scaffold/config/list.rb +7 -7
- data/lib/active_scaffold/config/mark.rb +2 -0
- data/lib/active_scaffold/config/nested.rb +28 -0
- data/lib/active_scaffold/config/search.rb +2 -0
- data/lib/active_scaffold/config/show.rb +2 -0
- data/lib/active_scaffold/config/subform.rb +2 -0
- data/lib/active_scaffold/config/update.rb +3 -1
- data/lib/active_scaffold/configurable.rb +4 -2
- data/lib/active_scaffold/constraints.rb +2 -0
- data/lib/active_scaffold/core.rb +14 -4
- data/lib/active_scaffold/data_structures/action_columns.rb +3 -1
- data/lib/active_scaffold/data_structures/action_link.rb +10 -0
- data/lib/active_scaffold/data_structures/action_link_separator.rb +2 -0
- data/lib/active_scaffold/data_structures/action_links.rb +32 -21
- data/lib/active_scaffold/data_structures/actions.rb +4 -2
- data/lib/active_scaffold/data_structures/association/abstract.rb +4 -2
- data/lib/active_scaffold/data_structures/association/active_mongoid.rb +4 -2
- data/lib/active_scaffold/data_structures/association/active_record.rb +3 -9
- data/lib/active_scaffold/data_structures/association/mongoid.rb +4 -2
- data/lib/active_scaffold/data_structures/association.rb +2 -0
- data/lib/active_scaffold/data_structures/bridge.rb +3 -1
- data/lib/active_scaffold/data_structures/column.rb +37 -3
- data/lib/active_scaffold/data_structures/columns.rb +4 -2
- data/lib/active_scaffold/data_structures/filter.rb +3 -3
- data/lib/active_scaffold/data_structures/filter_option.rb +2 -0
- data/lib/active_scaffold/data_structures/filters.rb +3 -3
- data/lib/active_scaffold/data_structures/nested_info.rb +4 -2
- data/lib/active_scaffold/data_structures/set.rb +8 -10
- data/lib/active_scaffold/data_structures/sorting.rb +5 -7
- data/lib/active_scaffold/engine.rb +3 -4
- data/lib/active_scaffold/extensions/action_controller_rendering.rb +2 -0
- data/lib/active_scaffold/extensions/action_controller_rescueing.rb +2 -0
- data/lib/active_scaffold/extensions/action_view_rendering.rb +2 -0
- data/lib/active_scaffold/extensions/connection_adapter.rb +2 -0
- data/lib/active_scaffold/extensions/ice_nine.rb +2 -0
- data/lib/active_scaffold/extensions/localize.rb +2 -0
- data/lib/active_scaffold/extensions/name_option_for_datetime.rb +2 -0
- data/lib/active_scaffold/extensions/paginator_extensions.rb +3 -1
- data/lib/active_scaffold/extensions/routing_mapper.rb +2 -0
- data/lib/active_scaffold/extensions/to_label.rb +2 -0
- data/lib/active_scaffold/extensions/unsaved_associated.rb +10 -8
- data/lib/active_scaffold/extensions/unsaved_record.rb +2 -0
- data/lib/active_scaffold/finder.rb +57 -18
- data/lib/active_scaffold/helpers/action_link_helpers.rb +112 -37
- data/lib/active_scaffold/helpers/association_helpers.rb +4 -2
- data/lib/active_scaffold/helpers/controller_helpers.rb +2 -0
- data/lib/active_scaffold/helpers/filter_helpers.rb +11 -3
- data/lib/active_scaffold/helpers/form_column_helpers.rb +98 -71
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +2 -0
- data/lib/active_scaffold/helpers/id_helpers.rb +2 -0
- data/lib/active_scaffold/helpers/list_column_helpers.rb +9 -5
- data/lib/active_scaffold/helpers/pagination_helpers.rb +3 -1
- data/lib/active_scaffold/helpers/search_column_helpers.rb +19 -9
- data/lib/active_scaffold/helpers/show_column_helpers.rb +4 -2
- data/lib/active_scaffold/helpers/tabs_helpers.rb +5 -3
- data/lib/active_scaffold/helpers/view_helpers.rb +3 -3
- data/lib/active_scaffold/marked_model.rb +6 -5
- data/lib/active_scaffold/orm_checks.rb +2 -0
- data/lib/active_scaffold/paginator.rb +4 -1
- data/lib/active_scaffold/registry.rb +2 -0
- data/lib/active_scaffold/responds_to_parent.rb +2 -0
- data/lib/active_scaffold/tableless.rb +23 -13
- data/lib/active_scaffold/version.rb +4 -2
- data/lib/active_scaffold.rb +10 -2
- data/lib/generators/active_scaffold/controller/USAGE +19 -0
- data/lib/generators/active_scaffold/controller/controller_generator.rb +29 -0
- data/lib/generators/active_scaffold/install/USAGE +2 -0
- data/lib/generators/active_scaffold/{install_generator.rb → install/install_generator.rb} +10 -6
- data/lib/generators/active_scaffold/resource/USAGE +29 -0
- data/lib/generators/active_scaffold/resource/resource_generator.rb +30 -0
- data/lib/tasks/brakeman.rake +2 -0
- data/shoulda_macros/macros.rb +2 -0
- metadata +19 -11
- data/lib/generators/active_scaffold/controller_generator.rb +0 -49
- data/lib/generators/active_scaffold/resource_generator.rb +0 -56
- /data/lib/generators/{templates → active_scaffold/controller/templates}/controller.rb +0 -0
- /data/lib/generators/{templates → active_scaffold/controller/templates}/helper.rb +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveScaffold::DataStructures
|
|
2
4
|
class Column
|
|
3
5
|
module ProxyableMethods
|
|
@@ -92,8 +94,16 @@ module ActiveScaffold::DataStructures
|
|
|
92
94
|
# a collection of associations to pre-load when finding the records on a page
|
|
93
95
|
attr_reader :includes
|
|
94
96
|
|
|
97
|
+
# a collection of associations to pre-load when the column is used as a subform,
|
|
98
|
+
# defaults to true, which means get associations from subform columns in the associated controller
|
|
99
|
+
# set to any other value to avoid checking the associated controller, false or nil to prevent preloading
|
|
100
|
+
attr_reader :subform_includes
|
|
101
|
+
|
|
95
102
|
# a place to store dev's column specific options
|
|
96
103
|
attr_writer :options
|
|
104
|
+
|
|
105
|
+
# define the fields to use with logical search
|
|
106
|
+
attr_accessor :logical_search
|
|
97
107
|
end
|
|
98
108
|
|
|
99
109
|
def inplace_edit=(value)
|
|
@@ -150,7 +160,7 @@ module ActiveScaffold::DataStructures
|
|
|
150
160
|
# update_columns = :name
|
|
151
161
|
# update_columns = [:name, :age]
|
|
152
162
|
def update_columns=(column_names)
|
|
153
|
-
@update_columns = Array
|
|
163
|
+
@update_columns = column_names.is_a?(Array) ? column_names : [column_names]
|
|
154
164
|
end
|
|
155
165
|
|
|
156
166
|
# sorting on a column can be configured four ways:
|
|
@@ -169,7 +179,7 @@ module ActiveScaffold::DataStructures
|
|
|
169
179
|
|
|
170
180
|
def sort
|
|
171
181
|
initialize_sort if @sort == true
|
|
172
|
-
@sort
|
|
182
|
+
@sort if @sort
|
|
173
183
|
end
|
|
174
184
|
|
|
175
185
|
def sortable?
|
|
@@ -181,6 +191,19 @@ module ActiveScaffold::DataStructures
|
|
|
181
191
|
self.sort = options
|
|
182
192
|
end
|
|
183
193
|
|
|
194
|
+
# a collection of associations to do left join when the list is sorted by this column
|
|
195
|
+
def sort_joins
|
|
196
|
+
@sort_joins || includes
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def sort_joins=(value)
|
|
200
|
+
@sort_joins =
|
|
201
|
+
case value
|
|
202
|
+
when Array then value
|
|
203
|
+
else [value] # automatically convert to an array
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
184
207
|
def associated_number?
|
|
185
208
|
@associated_number
|
|
186
209
|
end
|
|
@@ -283,6 +306,14 @@ module ActiveScaffold::DataStructures
|
|
|
283
306
|
end
|
|
284
307
|
end
|
|
285
308
|
|
|
309
|
+
def subform_includes=(value)
|
|
310
|
+
@subform_includes =
|
|
311
|
+
case value
|
|
312
|
+
when Array, TrueClass then value
|
|
313
|
+
else value ? [value] : value # not convert nil to [nil]
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
286
317
|
# a collection of associations to do left join when this column is included on search
|
|
287
318
|
def search_joins
|
|
288
319
|
@search_joins || includes
|
|
@@ -315,7 +346,7 @@ module ActiveScaffold::DataStructures
|
|
|
315
346
|
end
|
|
316
347
|
|
|
317
348
|
def searchable?
|
|
318
|
-
search_sql.present?
|
|
349
|
+
search_sql.present? || (logical_search.present? && ActiveScaffold::Finder::LOGICAL_COMPARATORS.present?)
|
|
319
350
|
end
|
|
320
351
|
|
|
321
352
|
def link
|
|
@@ -374,6 +405,7 @@ module ActiveScaffold::DataStructures
|
|
|
374
405
|
|
|
375
406
|
include ActiveScaffold::Configurable
|
|
376
407
|
include ActiveScaffold::OrmChecks
|
|
408
|
+
|
|
377
409
|
NO_PARAMS = Set.new.freeze
|
|
378
410
|
NO_OPTIONS = {}.freeze
|
|
379
411
|
|
|
@@ -512,6 +544,7 @@ module ActiveScaffold::DataStructures
|
|
|
512
544
|
if delegated_association
|
|
513
545
|
self.includes = includes ? [delegated_association.name => includes] : [delegated_association.name]
|
|
514
546
|
end
|
|
547
|
+
self.subform_includes = true if association
|
|
515
548
|
|
|
516
549
|
# default all the configurable variables
|
|
517
550
|
self.css_class = ''
|
|
@@ -522,6 +555,7 @@ module ActiveScaffold::DataStructures
|
|
|
522
555
|
validators_force_require_on.reject { |opt| opt == true }.flatten.presence
|
|
523
556
|
self.sort = true
|
|
524
557
|
self.search_sql = true
|
|
558
|
+
self.logical_search = [name] unless virtual? || association || tableless?
|
|
525
559
|
|
|
526
560
|
@weight = estimate_weight
|
|
527
561
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveScaffold::DataStructures
|
|
2
4
|
class Columns
|
|
3
5
|
include Enumerable
|
|
@@ -19,13 +21,13 @@ module ActiveScaffold::DataStructures
|
|
|
19
21
|
# This accessor is used by ActionColumns to create new Column objects without adding them to this set
|
|
20
22
|
attr_reader :active_record_class
|
|
21
23
|
|
|
22
|
-
def initialize(active_record_class, *
|
|
24
|
+
def initialize(active_record_class, *)
|
|
23
25
|
@active_record_class = active_record_class
|
|
24
26
|
@_inheritable = ::Set.new
|
|
25
27
|
@set = {}
|
|
26
28
|
@sorted = nil
|
|
27
29
|
|
|
28
|
-
add(*
|
|
30
|
+
add(*)
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
# the way to add columns to the set. this is primarily useful for virtual columns.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveScaffold::DataStructures
|
|
2
4
|
class Filter
|
|
3
5
|
include Enumerable
|
|
@@ -52,9 +54,7 @@ module ActiveScaffold::DataStructures
|
|
|
52
54
|
@options.each(&)
|
|
53
55
|
end
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
@options.empty?
|
|
57
|
-
end
|
|
57
|
+
delegate :empty?, to: :@options
|
|
58
58
|
|
|
59
59
|
def label(*)
|
|
60
60
|
case @label
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveScaffold::DataStructures
|
|
2
4
|
class Filters
|
|
3
5
|
include Enumerable
|
|
@@ -37,9 +39,7 @@ module ActiveScaffold::DataStructures
|
|
|
37
39
|
@set.each(&)
|
|
38
40
|
end
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
@set.empty?
|
|
42
|
-
end
|
|
42
|
+
delegate :empty?, to: :@set
|
|
43
43
|
|
|
44
44
|
# default filter type for all app filters, can be :links or :select
|
|
45
45
|
cattr_accessor :default_type
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveScaffold::DataStructures
|
|
2
4
|
class NestedInfo
|
|
3
5
|
def self.get(model, params)
|
|
@@ -31,7 +33,7 @@ module ActiveScaffold::DataStructures
|
|
|
31
33
|
false
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
def has_many? # rubocop:disable Naming/
|
|
36
|
+
def has_many? # rubocop:disable Naming/PredicatePrefix
|
|
35
37
|
false
|
|
36
38
|
end
|
|
37
39
|
|
|
@@ -39,7 +41,7 @@ module ActiveScaffold::DataStructures
|
|
|
39
41
|
false
|
|
40
42
|
end
|
|
41
43
|
|
|
42
|
-
def has_one? # rubocop:disable Naming/
|
|
44
|
+
def has_one? # rubocop:disable Naming/PredicatePrefix
|
|
43
45
|
false
|
|
44
46
|
end
|
|
45
47
|
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveScaffold::DataStructures
|
|
2
4
|
class Set
|
|
3
5
|
include Enumerable
|
|
4
6
|
include ActiveScaffold::Configurable
|
|
5
7
|
|
|
6
|
-
def initialize(*
|
|
7
|
-
set_values(*
|
|
8
|
+
def initialize(*)
|
|
9
|
+
set_values(*)
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
def initialize_dup(other)
|
|
11
13
|
@set = other.set.dup
|
|
12
14
|
end
|
|
13
15
|
|
|
14
|
-
def set_values(*
|
|
16
|
+
def set_values(*)
|
|
15
17
|
@set = []
|
|
16
|
-
add(*
|
|
18
|
+
add(*)
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
# the way to add items to the set.
|
|
@@ -52,13 +54,9 @@ module ActiveScaffold::DataStructures
|
|
|
52
54
|
end
|
|
53
55
|
|
|
54
56
|
# returns the number of items in the set
|
|
55
|
-
|
|
56
|
-
@set.length
|
|
57
|
-
end
|
|
57
|
+
delegate :length, to: :@set
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
@set.empty?
|
|
61
|
-
end
|
|
59
|
+
delegate :empty?, to: :@set
|
|
62
60
|
|
|
63
61
|
def +(other)
|
|
64
62
|
self.class.new(@set, *other)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveScaffold::DataStructures
|
|
2
4
|
# encapsulates the column sorting configuration for the List view
|
|
3
5
|
class Sorting
|
|
@@ -22,7 +24,7 @@ module ActiveScaffold::DataStructures
|
|
|
22
24
|
# fallback to setting primary key ordering
|
|
23
25
|
setup_primary_key_order_clause
|
|
24
26
|
model_scope = model.send(:build_default_scope)
|
|
25
|
-
order_clause = model_scope.order_values.join(',') if model_scope
|
|
27
|
+
order_clause = model_scope.order_values.map { |ordering| ordering.respond_to?(:to_sql) ? ordering.to_sql : ordering }.join(',') if model_scope
|
|
26
28
|
return unless order_clause
|
|
27
29
|
|
|
28
30
|
# If an ORDER BY clause is found set default sorting according to it
|
|
@@ -115,13 +117,9 @@ module ActiveScaffold::DataStructures
|
|
|
115
117
|
end
|
|
116
118
|
|
|
117
119
|
# provides quick access to the first (and sometimes only) clause
|
|
118
|
-
|
|
119
|
-
@clauses.first
|
|
120
|
-
end
|
|
120
|
+
delegate :first, to: :@clauses
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
@clauses.size
|
|
124
|
-
end
|
|
122
|
+
delegate :size, to: :@clauses
|
|
125
123
|
|
|
126
124
|
# builds an order-by clause
|
|
127
125
|
def clause(grouped_columns = nil)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveScaffold
|
|
2
4
|
class Engine < ::Rails::Engine
|
|
3
5
|
initializer 'active_scaffold.action_controller' do
|
|
@@ -30,6 +32,7 @@ module ActiveScaffold
|
|
|
30
32
|
require 'active_scaffold/extensions/unsaved_associated'
|
|
31
33
|
require 'active_scaffold/extensions/unsaved_record'
|
|
32
34
|
include ActiveScaffold::ActiveRecordPermissions::ModelUserAccess::Model
|
|
35
|
+
|
|
33
36
|
ActiveRecord::Associations.module_eval do
|
|
34
37
|
self::Association.include ActiveScaffold::Tableless::Association
|
|
35
38
|
self::CollectionAssociation.include ActiveScaffold::Tableless::CollectionAssociation
|
|
@@ -48,10 +51,6 @@ module ActiveScaffold
|
|
|
48
51
|
end
|
|
49
52
|
end
|
|
50
53
|
|
|
51
|
-
initializer 'active_scaffold.assets' do
|
|
52
|
-
config.assets.precompile << 'active_scaffold_manifest.js' if Rails::VERSION::MAJOR < 7
|
|
53
|
-
end
|
|
54
|
-
|
|
55
54
|
initializer 'active_scaffold.extensions' do
|
|
56
55
|
require 'active_scaffold/extensions/ice_nine'
|
|
57
56
|
require 'active_scaffold/extensions/localize'
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'active_scaffold/paginator'
|
|
2
4
|
|
|
3
5
|
module ActiveScaffold
|
|
@@ -27,7 +29,7 @@ module ActiveScaffold
|
|
|
27
29
|
if @pager.infinite?
|
|
28
30
|
items.to_a.empty?
|
|
29
31
|
else
|
|
30
|
-
@pager.count.zero?
|
|
32
|
+
@pager.count.zero? # rubocop:disable Style/CollectionQuerying -- @pager doesn't have none? method
|
|
31
33
|
end
|
|
32
34
|
end
|
|
33
35
|
end
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# save and validation support for associations.
|
|
2
4
|
class ActiveRecord::Base
|
|
3
|
-
def associated_valid?(path =
|
|
5
|
+
def associated_valid?(path = ::Set.new)
|
|
4
6
|
return true if path.include?(self) # prevent recursion (if associated and parent are new records)
|
|
5
7
|
|
|
6
8
|
path << self
|
|
7
9
|
# using [].all? syntax to avoid a short-circuit
|
|
8
10
|
# errors to associated record can be added by update_record_from_params when association fails to set and ActiveRecord::RecordNotSaved is raised
|
|
9
|
-
with_unsaved_associated { |a| [a.keeping_errors { a.valid? }, a.associated_valid?(path)].all? }
|
|
11
|
+
with_unsaved_associated { |a| [a.keeping_errors { a.valid? }, a.associated_valid?(path)].all? }.all?
|
|
10
12
|
end
|
|
11
13
|
|
|
12
|
-
def save_associated
|
|
13
|
-
with_unsaved_associated { |a| a.save && a.save_associated }
|
|
14
|
+
def save_associated # rubocop:disable Naming/PredicateMethod
|
|
15
|
+
with_unsaved_associated { |a| a.save && a.save_associated }.all?
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
def save_associated!
|
|
@@ -18,7 +20,7 @@ class ActiveRecord::Base
|
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
def no_errors_in_associated?
|
|
21
|
-
with_unsaved_associated { |a| a.errors.
|
|
23
|
+
with_unsaved_associated { |a| a.errors.none? && a.no_errors_in_associated? }.all?
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
protected
|
|
@@ -49,16 +51,16 @@ class ActiveRecord::Base
|
|
|
49
51
|
# returns false if any yield returns false.
|
|
50
52
|
# returns true otherwise, even when none of the associations have been instantiated. build wrapper methods accordingly.
|
|
51
53
|
def with_unsaved_associated(&block)
|
|
52
|
-
associations_for_update.
|
|
54
|
+
associations_for_update.flat_map do |assoc|
|
|
53
55
|
association_proxy = association(assoc.name)
|
|
54
56
|
if association_proxy.target.present?
|
|
55
57
|
records = association_proxy.target
|
|
56
58
|
records = [records] unless records.is_a? Array # convert singular associations into collections for ease of use
|
|
57
59
|
# must use select instead of find_all, which Rails overrides on association proxies for db access
|
|
58
|
-
records.select { |r| r.unsaved? && !r.readonly? }.map(&block)
|
|
60
|
+
records.select { |r| r.unsaved? && !r.readonly? }.map(&block)
|
|
59
61
|
else
|
|
60
62
|
true
|
|
61
63
|
end
|
|
62
|
-
end
|
|
64
|
+
end
|
|
63
65
|
end
|
|
64
66
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveScaffold
|
|
2
4
|
module Finder
|
|
3
5
|
def self.like_operator
|
|
@@ -106,7 +108,7 @@ module ActiveScaffold
|
|
|
106
108
|
args << session if method(column_method).arity == 4
|
|
107
109
|
return send(:"condition_for_#{column.name}_column", *args)
|
|
108
110
|
end
|
|
109
|
-
return unless column.
|
|
111
|
+
return unless column.searchable? && value.present?
|
|
110
112
|
|
|
111
113
|
search_ui = column.search_ui || column.column_type
|
|
112
114
|
begin
|
|
@@ -119,6 +121,7 @@ module ActiveScaffold
|
|
|
119
121
|
condition_for_search_ui(column, value, like_pattern, search_ui)
|
|
120
122
|
end
|
|
121
123
|
return nil unless sql
|
|
124
|
+
return sql if sql.is_a? ::ActiveRecord::Relation
|
|
122
125
|
|
|
123
126
|
where_values = []
|
|
124
127
|
sql_conditions = []
|
|
@@ -134,8 +137,9 @@ module ActiveScaffold
|
|
|
134
137
|
end
|
|
135
138
|
[sql_conditions.join(' OR '), *where_values]
|
|
136
139
|
rescue StandardError => e
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
message = "on the ActiveScaffold column :#{column.name}, search_ui = #{search_ui} in #{name}"
|
|
141
|
+
ActiveScaffold.log_exception(e, message)
|
|
142
|
+
raise e.class, "#{e.message} -- #{message}", e.backtrace
|
|
139
143
|
end
|
|
140
144
|
end
|
|
141
145
|
|
|
@@ -227,9 +231,40 @@ module ActiveScaffold
|
|
|
227
231
|
['(%<search_sql>s BETWEEN ? AND ?)', value[:from], value[:to]]
|
|
228
232
|
elsif ActiveScaffold::Finder::NUMERIC_COMPARATORS.include?(value[:opt])
|
|
229
233
|
["%<search_sql>s #{value[:opt]} ?", value[:from]]
|
|
234
|
+
elsif ActiveScaffold::Finder::LOGICAL_COMPARATORS.include?(value[:opt])
|
|
235
|
+
operator =
|
|
236
|
+
case value[:opt]
|
|
237
|
+
when 'all_tokens' then 'AND'
|
|
238
|
+
when 'any_token' then 'OR'
|
|
239
|
+
end
|
|
240
|
+
parser = ActiveScaffold::Bridges::LogicalQueryParser::TokensGrammar::Parser.new(operator) if operator
|
|
241
|
+
[logical_search_condition(column, value[:from], parser)]
|
|
230
242
|
end
|
|
231
243
|
end
|
|
232
244
|
|
|
245
|
+
def logical_search_condition(column, search, parser = nil)
|
|
246
|
+
model = column.active_record_class
|
|
247
|
+
subquery = alias_query_for_same_table_exists(model.all) if column.logical_search.any?(Hash)
|
|
248
|
+
query = ::LogicalQueryParser.search(search, subquery || model, columns: column.logical_search, parser: parser)
|
|
249
|
+
if subquery
|
|
250
|
+
model.where(same_table_exists_subquery(query))
|
|
251
|
+
else
|
|
252
|
+
query
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def alias_query_for_same_table_exists(query)
|
|
257
|
+
query.instance_variable_set(:@table, query.table.dup)
|
|
258
|
+
query.table.instance_variable_set(:@table_alias, "_#{query.table_name}_exists")
|
|
259
|
+
query
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def same_table_exists_subquery(query)
|
|
263
|
+
alias_query_for_same_table_exists(query) unless query.table.table_alias
|
|
264
|
+
subquery = query.where(query.arel_table[query.primary_key].eq(query.table[query.primary_key]))
|
|
265
|
+
subquery.select(1).arel.exists
|
|
266
|
+
end
|
|
267
|
+
|
|
233
268
|
def tables_for_translating_days_and_months(format)
|
|
234
269
|
keys = {
|
|
235
270
|
'%A' => 'date.day_names',
|
|
@@ -245,7 +280,8 @@ module ActiveScaffold
|
|
|
245
280
|
end
|
|
246
281
|
|
|
247
282
|
def translate_days_and_months(value, format)
|
|
248
|
-
translated = ''
|
|
283
|
+
translated = +''
|
|
284
|
+
value = value.dup # ensure the string can be changed
|
|
249
285
|
tables_for_translating_days_and_months(format).each do |table|
|
|
250
286
|
regexp = Regexp.union(table.keys)
|
|
251
287
|
index = value.index(regexp)
|
|
@@ -490,6 +526,7 @@ module ActiveScaffold
|
|
|
490
526
|
doesnt_begin_with: 'not_?%',
|
|
491
527
|
doesnt_end_with: 'not_%?'
|
|
492
528
|
}.freeze
|
|
529
|
+
LOGICAL_COMPARATORS = [].freeze
|
|
493
530
|
NULL_COMPARATORS = %w[null not_null].freeze
|
|
494
531
|
DATE_COMPARATORS = %w[PAST FUTURE RANGE].freeze
|
|
495
532
|
DATE_UNITS = %w[DAYS WEEKS MONTHS YEARS].freeze
|
|
@@ -502,12 +539,17 @@ module ActiveScaffold
|
|
|
502
539
|
|
|
503
540
|
protected
|
|
504
541
|
|
|
505
|
-
attr_writer :active_scaffold_conditions, :active_scaffold_preload, :active_scaffold_joins,
|
|
542
|
+
attr_writer :active_scaffold_conditions, :active_scaffold_preload, :active_scaffold_joins,
|
|
543
|
+
:active_scaffold_outer_joins, :active_scaffold_references, :active_scaffold_relations
|
|
506
544
|
|
|
507
545
|
def active_scaffold_conditions
|
|
508
546
|
@active_scaffold_conditions ||= []
|
|
509
547
|
end
|
|
510
548
|
|
|
549
|
+
def active_scaffold_relations
|
|
550
|
+
@active_scaffold_relations ||= []
|
|
551
|
+
end
|
|
552
|
+
|
|
511
553
|
def active_scaffold_preload
|
|
512
554
|
@active_scaffold_preload ||= []
|
|
513
555
|
end
|
|
@@ -516,16 +558,6 @@ module ActiveScaffold
|
|
|
516
558
|
@active_scaffold_joins ||= []
|
|
517
559
|
end
|
|
518
560
|
|
|
519
|
-
def active_scaffold_habtm_joins
|
|
520
|
-
ActiveScaffold.deprecator.warn 'use active_scaffold_joins'
|
|
521
|
-
active_scaffold_joins
|
|
522
|
-
end
|
|
523
|
-
|
|
524
|
-
def active_scaffold_habtm_joins=(value)
|
|
525
|
-
ActiveScaffold.deprecator.warn 'use active_scaffold_joins='
|
|
526
|
-
self.active_scaffold_joins = value
|
|
527
|
-
end
|
|
528
|
-
|
|
529
561
|
def active_scaffold_outer_joins
|
|
530
562
|
@active_scaffold_outer_joins ||= []
|
|
531
563
|
end
|
|
@@ -603,6 +635,7 @@ module ActiveScaffold
|
|
|
603
635
|
preload: active_scaffold_preload,
|
|
604
636
|
includes: active_scaffold_references.presence,
|
|
605
637
|
references: active_scaffold_references.presence,
|
|
638
|
+
relations: active_scaffold_relations.presence,
|
|
606
639
|
select: options[:select]
|
|
607
640
|
)
|
|
608
641
|
end
|
|
@@ -684,9 +717,15 @@ module ActiveScaffold
|
|
|
684
717
|
def append_to_query(relation, options)
|
|
685
718
|
options.assert_valid_keys :where, :select, :having, :group, :reorder, :order, :limit, :offset,
|
|
686
719
|
:joins, :left_joins, :left_outer_joins, :includes, :lock, :readonly,
|
|
687
|
-
:from, :conditions, :preload, :references
|
|
720
|
+
:from, :conditions, :preload, :references, :relations
|
|
688
721
|
relation = options.compact_blank.inject(relation) do |rel, (k, v)|
|
|
689
|
-
k == :conditions
|
|
722
|
+
if k == :conditions
|
|
723
|
+
apply_conditions(rel, *v)
|
|
724
|
+
elsif k == :relations
|
|
725
|
+
v.reduce(rel, :merge)
|
|
726
|
+
else
|
|
727
|
+
rel.send(k, v)
|
|
728
|
+
end
|
|
690
729
|
end
|
|
691
730
|
relation.distinct_value = true if options[:left_outer_joins].present? || options[:left_joins].present?
|
|
692
731
|
relation
|
|
@@ -717,7 +756,7 @@ module ActiveScaffold
|
|
|
717
756
|
def sort_collection_by_column(collection, column, order)
|
|
718
757
|
sorter = column.sort[:method]
|
|
719
758
|
collection = collection.sort_by do |record|
|
|
720
|
-
value = sorter.is_a?(Proc) ? record.
|
|
759
|
+
value = sorter.is_a?(Proc) ? record.instance_exec(record, &sorter) : record.instance_eval(sorter.to_s)
|
|
721
760
|
value = '' if value.nil?
|
|
722
761
|
value
|
|
723
762
|
end
|