active_scaffold 3.4.43 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|