active_scaffold 3.4.43 → 3.5.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 +39 -0
- data/{LICENSE → LICENSE.md} +1 -1
- data/README.md +27 -19
- data/app/assets/javascripts/active_scaffold.js.erb +1 -1
- data/app/assets/javascripts/jquery/active_scaffold.js +95 -43
- data/app/assets/javascripts/jquery/tiny_mce_bridge.js +30 -6
- data/app/assets/javascripts/prototype/tiny_mce_bridge.js +11 -1
- data/app/assets/stylesheets/active_scaffold_colors.scss +2 -2
- data/app/assets/stylesheets/active_scaffold_layout.css +36 -28
- data/app/views/active_scaffold_overrides/_base_form.html.erb +2 -3
- data/app/views/active_scaffold_overrides/_field_search.html.erb +8 -7
- data/app/views/active_scaffold_overrides/_form_association.html.erb +9 -9
- data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +6 -6
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +52 -50
- data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_human_conditions.html.erb +3 -1
- data/app/views/active_scaffold_overrides/_list_calculations.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_list_column_headings.html.erb +2 -0
- data/app/views/active_scaffold_overrides/_list_messages.html.erb +5 -3
- data/app/views/active_scaffold_overrides/_list_record.html.erb +3 -1
- data/app/views/active_scaffold_overrides/_list_with_header.html.erb +9 -9
- data/app/views/active_scaffold_overrides/_messages.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_refresh_list.js.erb +18 -10
- data/app/views/active_scaffold_overrides/_render_field.js.erb +3 -3
- data/app/views/active_scaffold_overrides/_search.html.erb +7 -6
- data/app/views/active_scaffold_overrides/_show_actions.html.erb +14 -0
- data/app/views/active_scaffold_overrides/_show_association.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_update_actions.html.erb +6 -2
- data/app/views/active_scaffold_overrides/_update_column.js.erb +1 -1
- data/app/views/active_scaffold_overrides/_update_form.html.erb +1 -1
- data/app/views/active_scaffold_overrides/destroy.js.erb +2 -3
- data/app/views/active_scaffold_overrides/edit_associated.js.erb +4 -3
- data/app/views/active_scaffold_overrides/on_action_update.js.erb +5 -3
- data/app/views/active_scaffold_overrides/on_create.js.erb +4 -4
- data/app/views/active_scaffold_overrides/on_update.js.erb +6 -6
- data/app/views/active_scaffold_overrides/show.html.erb +6 -0
- data/app/views/active_scaffold_overrides/update.html.erb +1 -1
- data/app/views/active_scaffold_overrides/update_column.js.erb +1 -1
- data/config/brakeman.ignore +26 -0
- data/config/brakeman.yml +3 -0
- data/config/i18n-tasks.yml +121 -0
- data/config/locales/de.yml +81 -70
- data/config/locales/en.yml +83 -74
- data/config/locales/es.yml +82 -73
- data/config/locales/fr.yml +86 -75
- data/config/locales/hu.yml +81 -70
- data/config/locales/ja.yml +71 -60
- data/config/locales/ru.yml +85 -74
- data/lib/active_scaffold.rb +3 -0
- data/lib/active_scaffold/actions/common_search.rb +11 -7
- data/lib/active_scaffold/actions/core.rb +119 -47
- data/lib/active_scaffold/actions/create.rb +1 -1
- data/lib/active_scaffold/actions/delete.rb +11 -8
- data/lib/active_scaffold/actions/field_search.rb +104 -6
- data/lib/active_scaffold/actions/list.rb +25 -21
- data/lib/active_scaffold/actions/mark.rb +12 -4
- data/lib/active_scaffold/actions/nested.rb +26 -26
- data/lib/active_scaffold/actions/search.rb +2 -2
- data/lib/active_scaffold/actions/show.rb +4 -5
- data/lib/active_scaffold/actions/subform.rb +9 -7
- data/lib/active_scaffold/actions/update.rb +20 -13
- data/lib/active_scaffold/active_record_permissions.rb +24 -5
- data/lib/active_scaffold/attribute_params.rb +68 -49
- data/lib/active_scaffold/bridges.rb +1 -1
- data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +15 -19
- data/lib/active_scaffold/bridges/bitfields.rb +1 -1
- data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +10 -14
- data/lib/active_scaffold/bridges/calendar_date_select.rb +0 -7
- data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +19 -22
- data/lib/active_scaffold/bridges/cancan.rb +4 -3
- data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +11 -21
- data/lib/active_scaffold/bridges/carrierwave.rb +2 -1
- data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +2 -6
- data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +6 -39
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/chosen.rb +4 -1
- data/lib/active_scaffold/bridges/chosen/helpers.rb +3 -2
- data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +2 -2
- data/lib/active_scaffold/bridges/date_picker.rb +3 -0
- data/lib/active_scaffold/bridges/date_picker/ext.rb +43 -38
- data/lib/active_scaffold/bridges/date_picker/helper.rb +24 -23
- data/lib/active_scaffold/bridges/dragonfly.rb +1 -1
- data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +3 -7
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -25
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +2 -2
- data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +6 -8
- data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +0 -2
- data/lib/active_scaffold/bridges/file_column/list_ui.rb +2 -1
- data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +1 -1
- data/lib/active_scaffold/bridges/paper_trail/actions.rb +1 -1
- data/lib/active_scaffold/bridges/paper_trail/helper.rb +1 -2
- data/lib/active_scaffold/bridges/paper_trail/paper_trail_bridge.rb +3 -7
- data/lib/active_scaffold/bridges/paperclip.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -28
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +3 -7
- data/lib/active_scaffold/bridges/record_select.rb +2 -0
- data/lib/active_scaffold/bridges/record_select/helpers.rb +14 -18
- data/lib/active_scaffold/bridges/semantic_attributes/column.rb +4 -8
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +20 -20
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +7 -22
- data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +14 -14
- data/lib/active_scaffold/config/base.rb +9 -6
- data/lib/active_scaffold/config/core.rb +30 -21
- data/lib/active_scaffold/config/create.rb +2 -1
- data/lib/active_scaffold/config/delete.rb +2 -2
- data/lib/active_scaffold/config/field_search.rb +9 -3
- data/lib/active_scaffold/config/form.rb +4 -4
- data/lib/active_scaffold/config/list.rb +27 -23
- data/lib/active_scaffold/config/nested.rb +4 -4
- data/lib/active_scaffold/config/search.rb +6 -6
- data/lib/active_scaffold/config/show.rb +11 -1
- data/lib/active_scaffold/config/subform.rb +1 -1
- data/lib/active_scaffold/config/update.rb +4 -2
- data/lib/active_scaffold/constraints.rb +39 -36
- data/lib/active_scaffold/core.rb +36 -15
- data/lib/active_scaffold/data_structures/action_columns.rb +14 -9
- data/lib/active_scaffold/data_structures/action_link.rb +4 -5
- data/lib/active_scaffold/data_structures/action_links.rb +5 -4
- data/lib/active_scaffold/data_structures/actions.rb +2 -2
- data/lib/active_scaffold/data_structures/association.rb +8 -0
- data/lib/active_scaffold/data_structures/association/abstract.rb +147 -0
- data/lib/active_scaffold/data_structures/association/active_mongoid.rb +42 -0
- data/lib/active_scaffold/data_structures/association/active_record.rb +94 -0
- data/lib/active_scaffold/data_structures/association/mongoid.rb +45 -0
- data/lib/active_scaffold/data_structures/bridge.rb +3 -6
- data/lib/active_scaffold/data_structures/column.rb +100 -82
- data/lib/active_scaffold/data_structures/columns.rb +21 -3
- data/lib/active_scaffold/data_structures/nested_info.rb +22 -37
- data/lib/active_scaffold/data_structures/set.rb +4 -4
- data/lib/active_scaffold/data_structures/sorting.rb +29 -15
- data/lib/active_scaffold/engine.rb +3 -1
- data/lib/active_scaffold/extensions/action_controller_rendering.rb +10 -5
- data/lib/active_scaffold/extensions/action_view_rendering.rb +65 -59
- data/lib/active_scaffold/extensions/left_outer_joins.rb +48 -53
- data/lib/active_scaffold/extensions/localize.rb +3 -4
- data/lib/active_scaffold/extensions/name_option_for_datetime.rb +7 -11
- data/lib/active_scaffold/extensions/paginator_extensions.rb +20 -18
- data/lib/active_scaffold/extensions/routing_mapper.rb +104 -40
- data/lib/active_scaffold/extensions/to_label.rb +1 -1
- data/lib/active_scaffold/extensions/unsaved_associated.rb +4 -13
- data/lib/active_scaffold/extensions/unsaved_record.rb +12 -1
- data/lib/active_scaffold/finder.rb +200 -134
- data/lib/active_scaffold/helpers/action_link_helpers.rb +398 -0
- data/lib/active_scaffold/helpers/association_helpers.rb +12 -30
- data/lib/active_scaffold/helpers/controller_helpers.rb +74 -24
- data/lib/active_scaffold/helpers/form_column_helpers.rb +205 -112
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +21 -11
- data/lib/active_scaffold/helpers/id_helpers.rb +1 -1
- data/lib/active_scaffold/helpers/list_column_helpers.rb +117 -39
- data/lib/active_scaffold/helpers/pagination_helpers.rb +11 -14
- data/lib/active_scaffold/helpers/search_column_helpers.rb +69 -32
- data/lib/active_scaffold/helpers/show_column_helpers.rb +9 -3
- data/lib/active_scaffold/helpers/view_helpers.rb +41 -426
- data/lib/active_scaffold/orm_checks.rb +109 -0
- data/lib/active_scaffold/paginator.rb +1 -1
- data/lib/active_scaffold/responds_to_parent.rb +12 -10
- data/lib/active_scaffold/tableless.rb +81 -43
- data/lib/active_scaffold/version.rb +2 -2
- data/lib/generators/active_scaffold/controller_generator.rb +49 -0
- data/lib/generators/active_scaffold/install_generator.rb +45 -0
- data/lib/generators/active_scaffold/resource_generator.rb +56 -0
- data/lib/generators/{active_scaffold_controller/templates → templates}/controller.rb +0 -0
- data/lib/generators/{active_scaffold_controller/templates → templates}/helper.rb +0 -0
- data/shoulda_macros/macros.rb +3 -3
- data/test/active_scaffold_config_mock.rb +33 -0
- data/test/bridges/bridge_test.rb +9 -9
- data/test/bridges/date_picker_test.rb +3 -1
- data/test/bridges/paper_trail_test.rb +2 -3
- data/test/bridges/paperclip_test.rb +21 -10
- data/test/bridges/tiny_mce_test.rb +20 -21
- data/test/class_with_finder.rb +42 -0
- data/test/company.rb +6 -4
- data/test/config/core_test.rb +1 -1
- data/test/config/create_test.rb +1 -1
- data/test/config/list_test.rb +3 -3
- data/test/config/update_test.rb +3 -3
- data/test/data_structures/action_columns_test.rb +3 -3
- data/test/data_structures/association_column_test.rb +5 -5
- data/test/data_structures/column_test.rb +14 -14
- data/test/data_structures/columns_test.rb +2 -2
- data/test/data_structures/set_test.rb +2 -2
- data/test/data_structures/sorting_test.rb +6 -4
- data/test/extensions/active_record_test.rb +1 -1
- data/test/extensions/routing_mapper_test.rb +64 -13
- data/test/helpers/form_column_helpers_test.rb +6 -6
- data/test/helpers/list_column_helpers_test.rb +9 -5
- data/test/helpers/pagination_helpers_test.rb +1 -0
- data/test/misc/active_record_permissions_test.rb +18 -1
- data/test/misc/attribute_params_test.rb +26 -17
- data/test/misc/calculation_test.rb +8 -31
- data/test/misc/configurable_test.rb +3 -2
- data/test/misc/constraints_test.rb +33 -22
- data/test/misc/convert_numbers_format_test.rb +28 -10
- data/test/misc/finder_test.rb +6 -29
- data/test/misc/parse_datetime_test.rb +160 -0
- data/test/misc/render_test.rb +1 -1
- data/test/misc/tableless_test.rb +24 -0
- data/test/mock_app/app/models/building.rb +2 -1
- data/test/mock_app/config.ru +1 -1
- data/test/mock_app/config/environments/test.rb +1 -1
- data/test/mock_app/config/routes.rb +11 -3
- data/test/model_stub.rb +11 -6
- data/test/run_all.rb +1 -1
- data/test/test_helper.rb +19 -4
- metadata +42 -23
- data/lib/active_scaffold/data_structures/error_message.rb +0 -22
- data/lib/active_scaffold/extensions/reverse_associations.rb +0 -119
- data/lib/generators/active_scaffold/USAGE +0 -29
- data/lib/generators/active_scaffold/active_scaffold_generator.rb +0 -21
- data/lib/generators/active_scaffold_controller/USAGE +0 -19
- data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +0 -29
- data/test/data_structures/error_message_test.rb +0 -25
@@ -24,7 +24,7 @@ module ActiveScaffold::DataStructures
|
|
24
24
|
@_inheritable = []
|
25
25
|
@set = []
|
26
26
|
|
27
|
-
add
|
27
|
+
add(*args)
|
28
28
|
end
|
29
29
|
|
30
30
|
# the way to add columns to the set. this is primarily useful for virtual columns.
|
@@ -38,7 +38,25 @@ module ActiveScaffold::DataStructures
|
|
38
38
|
# then add columns to @set (unless they already exist)
|
39
39
|
args.each { |a| @set << ActiveScaffold::DataStructures::Column.new(a.to_sym, @active_record_class) unless find_by_name(a) }
|
40
40
|
end
|
41
|
-
|
41
|
+
alias << add
|
42
|
+
|
43
|
+
# add columns from association (belongs_to or has_one)
|
44
|
+
# these columns will use label translation from association model
|
45
|
+
# they will be excluded, so won't be included in action columns
|
46
|
+
# association columns will work for read actions only, not in form actions (create, update, subform)
|
47
|
+
def add_association_columns(association, *columns)
|
48
|
+
column = self[association]
|
49
|
+
raise ArgumentError, "unknown column #{association}" if column.nil?
|
50
|
+
raise ArgumentError, "column #{association} is not an association" if column.association.nil?
|
51
|
+
raise ArugmentError, "column #{association} is not singular association" unless column.association.singular?
|
52
|
+
raise ArugmentError, "column #{association} is polymorphic association" if column.association.polymorphic?
|
53
|
+
|
54
|
+
klass = column.association.klass
|
55
|
+
columns.each do |col|
|
56
|
+
next if find_by_name col
|
57
|
+
@set << ActiveScaffold::DataStructures::Column.new(col, klass, column.association)
|
58
|
+
end
|
59
|
+
end
|
42
60
|
|
43
61
|
def exclude(*args)
|
44
62
|
# only remove columns from _inheritable. we never want to completely forget about a column.
|
@@ -56,7 +74,7 @@ module ActiveScaffold::DataStructures
|
|
56
74
|
column = @set.find { |c| c == name }
|
57
75
|
column
|
58
76
|
end
|
59
|
-
|
77
|
+
alias [] find_by_name
|
60
78
|
|
61
79
|
def each
|
62
80
|
@set.each { |i| yield i }
|
@@ -63,7 +63,7 @@ module ActiveScaffold::DataStructures
|
|
63
63
|
false
|
64
64
|
end
|
65
65
|
|
66
|
-
def sorted?
|
66
|
+
def sorted?(*)
|
67
67
|
false
|
68
68
|
end
|
69
69
|
end
|
@@ -71,27 +71,15 @@ module ActiveScaffold::DataStructures
|
|
71
71
|
class NestedInfoAssociation < NestedInfo
|
72
72
|
def initialize(model, params)
|
73
73
|
super
|
74
|
-
|
75
|
-
@param_name =
|
74
|
+
column = parent_scaffold.active_scaffold_config.columns[params[:association].to_sym]
|
75
|
+
@param_name = column.model.name.foreign_key.to_sym
|
76
76
|
@parent_id = params[@param_name]
|
77
|
-
|
77
|
+
@association = column.try(:association)
|
78
|
+
@child_association = association.reverse_association(model) if association
|
79
|
+
setup_constrained_fields
|
78
80
|
end
|
79
81
|
|
80
|
-
delegate :name, :to => :association
|
81
|
-
|
82
|
-
def has_many?
|
83
|
-
association.macro == :has_many
|
84
|
-
end
|
85
|
-
|
86
|
-
def habtm?
|
87
|
-
association.macro == :has_and_belongs_to_many
|
88
|
-
end
|
89
|
-
|
90
|
-
delegate :belongs_to?, :to => :association
|
91
|
-
|
92
|
-
def has_one?
|
93
|
-
association.macro == :has_one
|
94
|
-
end
|
82
|
+
delegate :name, :belongs_to?, :has_one?, :has_many?, :habtm?, :readonly?, :to => :association
|
95
83
|
|
96
84
|
# A through association with has_one or has_many as source association
|
97
85
|
# create cannot be called in nested through associations, and not-nested through associations
|
@@ -101,28 +89,25 @@ module ActiveScaffold::DataStructures
|
|
101
89
|
def readonly_through_association?(columns)
|
102
90
|
return false unless through_association?
|
103
91
|
return true if association.through_reflection.options[:through]
|
104
|
-
association.source_reflection.
|
92
|
+
!association.source_reflection.belongs_to? && (
|
105
93
|
!child_association || !columns.include?(child_association.through_reflection.name)
|
106
94
|
)
|
107
95
|
end
|
108
96
|
|
109
97
|
def through_association?
|
110
|
-
association.
|
98
|
+
association.through?
|
111
99
|
end
|
112
100
|
|
113
|
-
def
|
114
|
-
|
101
|
+
def sorted?(chain)
|
102
|
+
default_sorting(chain).present?
|
115
103
|
end
|
116
104
|
|
117
|
-
def
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
association.options[:order]
|
124
|
-
elsif association.respond_to?(:scope) # rails 4
|
125
|
-
association.klass.class_eval(&association.scope).values[:order] if association.scope.is_a? Proc
|
105
|
+
def default_sorting(chain)
|
106
|
+
return @default_sorting if defined? @default_sorting
|
107
|
+
if association.scope.is_a?(Proc) && chain.respond_to?(:values) && chain.values[:order]
|
108
|
+
@default_sorting = chain.values[:order]
|
109
|
+
@default_sorting = @default_sorting.map(&:to_sql) if @default_sorting[0].is_a? Arel::Nodes::Node
|
110
|
+
@default_sorting = @default_sorting.join(', ')
|
126
111
|
end
|
127
112
|
end
|
128
113
|
|
@@ -132,12 +117,12 @@ module ActiveScaffold::DataStructures
|
|
132
117
|
|
133
118
|
protected
|
134
119
|
|
135
|
-
def
|
120
|
+
def setup_constrained_fields
|
136
121
|
@constrained_fields = []
|
137
|
-
constrained_fields << Array(association.foreign_key).map(&:to_sym) unless association.belongs_to?
|
138
|
-
|
139
|
-
|
140
|
-
|
122
|
+
@constrained_fields << Array(association.foreign_key).map(&:to_sym) unless association.belongs_to?
|
123
|
+
if child_association && child_association != association
|
124
|
+
@constrained_fields << child_association.name
|
125
|
+
end
|
141
126
|
end
|
142
127
|
end
|
143
128
|
|
@@ -9,7 +9,7 @@ module ActiveScaffold::DataStructures
|
|
9
9
|
|
10
10
|
def set_values(*args)
|
11
11
|
@set = []
|
12
|
-
add
|
12
|
+
add(*args)
|
13
13
|
end
|
14
14
|
|
15
15
|
# the way to add items to the set.
|
@@ -20,7 +20,7 @@ module ActiveScaffold::DataStructures
|
|
20
20
|
@set << arg unless @set.include? arg # avoid duplicates
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
alias << add
|
24
24
|
|
25
25
|
# the way to remove items from the set.
|
26
26
|
def exclude(*args)
|
@@ -29,7 +29,7 @@ module ActiveScaffold::DataStructures
|
|
29
29
|
# check respond_to? :to_sym, ActionColumns doesn't respond to to_sym
|
30
30
|
@set.reject! { |c| c.respond_to?(:to_sym) && args.include?(c.to_sym) } # reject all items specified
|
31
31
|
end
|
32
|
-
|
32
|
+
alias remove exclude
|
33
33
|
|
34
34
|
# returns an array of items with the provided names
|
35
35
|
def find_by_names(*names)
|
@@ -42,7 +42,7 @@ module ActiveScaffold::DataStructures
|
|
42
42
|
item = @set.find { |c| c == name }
|
43
43
|
item
|
44
44
|
end
|
45
|
-
|
45
|
+
alias [] find_by_name
|
46
46
|
|
47
47
|
def each
|
48
48
|
@set.each { |i| yield i }
|
@@ -2,19 +2,24 @@ module ActiveScaffold::DataStructures
|
|
2
2
|
# encapsulates the column sorting configuration for the List view
|
3
3
|
class Sorting
|
4
4
|
include Enumerable
|
5
|
+
include ActiveScaffold::OrmChecks
|
5
6
|
|
6
7
|
attr_accessor :constraint_columns
|
7
8
|
attr_accessor :sorting_by_primary_key # enabled by default for postgres
|
9
|
+
attr_reader :model
|
10
|
+
alias active_record_class model
|
8
11
|
|
9
|
-
def initialize(columns)
|
12
|
+
def initialize(columns, model)
|
10
13
|
@columns = columns
|
11
14
|
@clauses = []
|
12
15
|
@constraint_columns = []
|
16
|
+
@model = model
|
13
17
|
end
|
14
18
|
|
15
|
-
def set_default_sorting
|
19
|
+
def set_default_sorting
|
20
|
+
return unless active_record?
|
16
21
|
# fallback to setting primary key ordering
|
17
|
-
setup_primary_key_order_clause
|
22
|
+
setup_primary_key_order_clause
|
18
23
|
model_scope = model.send(:build_default_scope)
|
19
24
|
order_clause = model_scope.order_values.join(',') if model_scope
|
20
25
|
return unless order_clause
|
@@ -34,7 +39,7 @@ module ActiveScaffold::DataStructures
|
|
34
39
|
direction = direction.to_s.upcase
|
35
40
|
column = get_column(column_name)
|
36
41
|
raise ArgumentError, "Could not find column #{column_name}" if column.nil?
|
37
|
-
raise ArgumentError, 'Sorting direction unknown' unless [
|
42
|
+
raise ArgumentError, 'Sorting direction unknown' unless %i[ASC DESC].include? direction.to_sym
|
38
43
|
@clauses << [column, direction.untaint] if column.sortable?
|
39
44
|
raise ArgumentError, "Can't mix :method- and :sql-based sorting" if mixed_sorting?
|
40
45
|
end
|
@@ -77,8 +82,8 @@ module ActiveScaffold::DataStructures
|
|
77
82
|
clause[1]
|
78
83
|
end
|
79
84
|
|
80
|
-
SORTING_STAGES = Hash[%w
|
81
|
-
DEFAULT_SORTING_STAGES = Hash[%w
|
85
|
+
SORTING_STAGES = Hash[%w[reset ASC DESC reset].each_cons(2).to_a].freeze
|
86
|
+
DEFAULT_SORTING_STAGES = Hash[%w[ASC DESC ASC].each_cons(2).to_a].freeze
|
82
87
|
def next_sorting_of(column, sorted_by_default)
|
83
88
|
stages = sorted_by_default ? DEFAULT_SORTING_STAGES : SORTING_STAGES
|
84
89
|
stages[direction_of(column)] || 'ASC'
|
@@ -103,21 +108,30 @@ module ActiveScaffold::DataStructures
|
|
103
108
|
@clauses.first
|
104
109
|
end
|
105
110
|
|
111
|
+
def size
|
112
|
+
@clauses.size
|
113
|
+
end
|
114
|
+
|
106
115
|
# builds an order-by clause
|
107
|
-
def clause
|
116
|
+
def clause(grouped_columns_calculations = nil)
|
108
117
|
return nil if sorts_by_method? || default_sorting?
|
109
118
|
|
110
119
|
# unless the sorting is by method, create the sql string
|
111
120
|
order = []
|
112
121
|
each do |sort_column, sort_direction|
|
113
122
|
next if constraint_columns.include? sort_column.name
|
114
|
-
sql = sort_column.sort[:sql]
|
115
|
-
next if sql.
|
123
|
+
sql = grouped_columns_calculations.try(:dig, sort_column.name) || sort_column.sort[:sql]
|
124
|
+
next if sql.blank?
|
125
|
+
sql = sql.to_sql if sql.respond_to?(:to_sql)
|
116
126
|
|
117
|
-
|
127
|
+
parts = Array(sql).map do |column|
|
128
|
+
mongoid? ? [column, sort_direction] : "#{column} #{sort_direction}"
|
129
|
+
end
|
130
|
+
order << parts
|
118
131
|
end
|
119
132
|
|
120
133
|
order << @primary_key_order_clause if @sorting_by_primary_key
|
134
|
+
order.flatten!(1)
|
121
135
|
order unless order.empty?
|
122
136
|
end
|
123
137
|
|
@@ -149,7 +163,7 @@ module ActiveScaffold::DataStructures
|
|
149
163
|
def set_sorting_from_order_clause(order_clause, model_table_name = nil)
|
150
164
|
clear
|
151
165
|
order_clause.to_s.split(',').each do |criterion|
|
152
|
-
|
166
|
+
if criterion.present?
|
153
167
|
order_parts = extract_order_parts(criterion)
|
154
168
|
add(order_parts[:column_name], order_parts[:direction]) unless different_table?(model_table_name, order_parts[:table_name]) || get_column(order_parts[:column_name]).nil?
|
155
169
|
end
|
@@ -178,22 +192,22 @@ module ActiveScaffold::DataStructures
|
|
178
192
|
end
|
179
193
|
|
180
194
|
def extract_direction(direction_part)
|
181
|
-
if direction_part.to_s.
|
195
|
+
if direction_part.to_s.casecmp('DESC').zero?
|
182
196
|
'DESC'
|
183
197
|
else
|
184
198
|
'ASC'
|
185
199
|
end
|
186
200
|
end
|
187
201
|
|
188
|
-
def postgres?
|
202
|
+
def postgres?
|
189
203
|
model.connection.try(:adapter_name) == 'PostgreSQL'
|
190
204
|
end
|
191
205
|
|
192
|
-
def setup_primary_key_order_clause
|
206
|
+
def setup_primary_key_order_clause
|
193
207
|
return unless model.column_names.include?(model.primary_key)
|
194
208
|
set([model.primary_key, 'ASC'])
|
195
209
|
@primary_key_order_clause = clause
|
196
|
-
@sorting_by_primary_key = postgres?
|
210
|
+
@sorting_by_primary_key = postgres? # mandatory for postgres, so enabled by default
|
197
211
|
end
|
198
212
|
end
|
199
213
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# wrap the action rendering for ActiveScaffold controllers
|
2
|
-
module
|
3
|
-
|
4
|
-
def
|
2
|
+
module ActiveScaffold
|
3
|
+
module ActionController #:nodoc:
|
4
|
+
def render(*args, &block)
|
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
|
@@ -11,9 +11,14 @@ module ActionController #:nodoc:
|
|
11
11
|
:use_full_path => true, :layout => false, :content_type => :html
|
12
12
|
@rendering_adapter = nil # recursion control
|
13
13
|
else
|
14
|
-
|
14
|
+
super(*args, &block)
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module ActionController
|
21
|
+
class Base
|
22
|
+
prepend ActiveScaffold::ActionController
|
18
23
|
end
|
19
24
|
end
|
@@ -1,16 +1,15 @@
|
|
1
|
-
module
|
2
|
-
|
1
|
+
module ActiveScaffold
|
2
|
+
module LookupContext
|
3
3
|
attr_accessor :last_template
|
4
4
|
|
5
|
-
def
|
6
|
-
self.last_template =
|
5
|
+
def find_template(name, prefixes = [], partial = false, keys = [], options = {})
|
6
|
+
self.last_template = super(name, prefixes, partial, keys, options)
|
7
7
|
end
|
8
|
-
alias_method_chain :find_template, :last_template
|
9
8
|
end
|
10
9
|
end
|
11
10
|
|
12
11
|
# wrap the action rendering for ActiveScaffold views
|
13
|
-
module
|
12
|
+
module ActiveScaffold #:nodoc:
|
14
13
|
module RenderingHelper
|
15
14
|
#
|
16
15
|
# Adds two rendering options.
|
@@ -34,52 +33,11 @@ module ActionView::Helpers #:nodoc:
|
|
34
33
|
#
|
35
34
|
# Defining options[:label] lets you completely customize the list title for the embedded scaffold.
|
36
35
|
#
|
37
|
-
|
36
|
+
# options[:xhr] force to load embedded scaffold with AJAX even when render_component gem is installed.
|
37
|
+
#
|
38
|
+
def render(*args, &block)
|
38
39
|
if args.first.is_a?(Hash) && args.first[:active_scaffold]
|
39
|
-
|
40
|
-
options = args.first
|
41
|
-
|
42
|
-
remote_controller = options[:active_scaffold]
|
43
|
-
constraints = options[:constraints]
|
44
|
-
conditions = options[:conditions]
|
45
|
-
eid = Digest::MD5.hexdigest(params[:controller] + remote_controller.to_s + constraints.to_s + conditions.to_s)
|
46
|
-
eid_info = session["as:#{eid}"] ||= {}
|
47
|
-
if constraints
|
48
|
-
eid_info['constraints'] = constraints
|
49
|
-
else
|
50
|
-
eid_info.delete 'constraints'
|
51
|
-
end
|
52
|
-
if conditions
|
53
|
-
eid_info['conditions'] = conditions
|
54
|
-
else
|
55
|
-
eid_info.delete 'conditions'
|
56
|
-
end
|
57
|
-
if options[:label]
|
58
|
-
eid_info['list'] = {'label' => options[:label]}
|
59
|
-
else
|
60
|
-
eid_info.delete 'list'
|
61
|
-
end
|
62
|
-
session.delete "as:#{eid}" if eid_info.empty?
|
63
|
-
options[:params] ||= {}
|
64
|
-
options[:params].merge! :eid => eid, :embedded => true
|
65
|
-
|
66
|
-
id = "as_#{eid}-embedded"
|
67
|
-
url_options = {:controller => remote_controller.to_s, :action => 'index'}.merge(options[:params])
|
68
|
-
|
69
|
-
if controller.respond_to?(:render_component_into_view, true)
|
70
|
-
controller.send(:render_component_into_view, url_options)
|
71
|
-
else
|
72
|
-
url = url_for(url_options)
|
73
|
-
content_tag(:div, :id => id, :class => 'active-scaffold-component', :data => {:refresh => url}) do
|
74
|
-
# parse the ActiveRecord model name from the controller path, which
|
75
|
-
# might be a namespaced controller (e.g., 'admin/admins')
|
76
|
-
model = remote_controller.to_s.sub(/.*\//, '').singularize
|
77
|
-
content_tag(:div, :class => 'active-scaffold-header') do
|
78
|
-
content_tag :h2, link_to(args.first[:label] || active_scaffold_config_for(model).list.label, url, :remote => true, :class => 'load-embedded')
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
40
|
+
render_embedded args.first
|
83
41
|
elsif args.first == :super
|
84
42
|
@_view_paths ||= lookup_context.view_paths.clone
|
85
43
|
@_last_template ||= lookup_context.last_template
|
@@ -102,30 +60,78 @@ module ActionView::Helpers #:nodoc:
|
|
102
60
|
last_view_path = File.expand_path(File.dirname(File.dirname(lookup_context.last_template.inspect)), Rails.root)
|
103
61
|
lookup_context.view_paths = view_paths.drop(view_paths.find_index { |path| path.to_s == last_view_path } + 1)
|
104
62
|
end
|
105
|
-
result =
|
63
|
+
result = super options
|
106
64
|
lookup_context.view_paths = @_view_paths if @_view_paths
|
107
65
|
lookup_context.last_template = @_last_template if @_last_template
|
108
66
|
result
|
109
67
|
else
|
110
68
|
@_view_paths ||= lookup_context.view_paths.clone
|
111
69
|
last_template = lookup_context.last_template
|
112
|
-
if args[0].is_a?(Hash)
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
70
|
+
current_view = if args[0].is_a?(Hash)
|
71
|
+
{:locals => args[0][:locals], :object => args[0][:object]}
|
72
|
+
else # call is render 'partial', locals_hash
|
73
|
+
{:locals => args[1]}
|
74
|
+
end
|
117
75
|
view_stack << current_view if current_view
|
118
76
|
lookup_context.view_paths = @_view_paths # reset view_paths in case a view render :super, and then render :partial
|
119
|
-
result =
|
77
|
+
result = super
|
120
78
|
view_stack.pop if current_view.present?
|
121
79
|
lookup_context.last_template = last_template
|
122
80
|
result
|
123
81
|
end
|
124
82
|
end
|
125
|
-
alias_method_chain :render, :active_scaffold
|
126
83
|
|
127
84
|
def view_stack
|
128
85
|
@_view_stack ||= []
|
129
86
|
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def render_embedded(options)
|
91
|
+
require 'digest/md5'
|
92
|
+
|
93
|
+
remote_controller = options[:active_scaffold]
|
94
|
+
# It is important that the EID hash remains short as to not contribute
|
95
|
+
# to a large session size and thus a possible cookie overflow exception
|
96
|
+
# when using rails CookieStore or EncryptedCookieStore. For example,
|
97
|
+
# when rendering many embedded scaffolds with constraints or conditions
|
98
|
+
# on a single page.
|
99
|
+
eid = Digest::MD5.hexdigest(params[:controller] + options.to_s)
|
100
|
+
eid_info = {loading: true}
|
101
|
+
eid_info[:constraints] = options[:constraints] if options[:constraints]
|
102
|
+
eid_info[:conditions] = options[:conditions] if options[:conditions]
|
103
|
+
eid_info[:label] = options[:label] if options[:label]
|
104
|
+
options[:params] ||= {}
|
105
|
+
options[:params].merge! :eid => eid, :embedded => eid_info
|
106
|
+
|
107
|
+
id = "as_#{eid}-embedded"
|
108
|
+
url_options = {controller: remote_controller.to_s, action: 'index', id: nil}.merge(options[:params])
|
109
|
+
|
110
|
+
if controller.respond_to?(:render_component_into_view, true) && !options[:xhr]
|
111
|
+
controller.send(:render_component_into_view, url_options)
|
112
|
+
else
|
113
|
+
url = url_for(url_options)
|
114
|
+
content_tag(:div, :id => id, :class => 'active-scaffold-component', :data => {:refresh => url}) do
|
115
|
+
# parse the ActiveRecord model name from the controller path, which
|
116
|
+
# might be a namespaced controller (e.g., 'admin/admins')
|
117
|
+
model = remote_controller.to_s.sub(/.*\//, '').singularize
|
118
|
+
content_tag(:div, :class => 'active-scaffold-header') do
|
119
|
+
content_tag :h2, link_to(options[:label] || active_scaffold_config_for(model).list.label, url, :remote => true, :class => 'load-embedded')
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
module ActionView
|
128
|
+
LookupContext.class_eval do
|
129
|
+
prepend ActiveScaffold::LookupContext
|
130
|
+
end
|
131
|
+
|
132
|
+
module Helpers
|
133
|
+
Base.class_eval do
|
134
|
+
include ActiveScaffold::RenderingHelper
|
135
|
+
end
|
130
136
|
end
|
131
137
|
end
|