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
@@ -0,0 +1,398 @@
|
|
1
|
+
module ActiveScaffold
|
2
|
+
module Helpers
|
3
|
+
# All extra helpers that should be included in the View.
|
4
|
+
# Also a dumping ground for uncategorized helpers.
|
5
|
+
module ActionLinkHelpers
|
6
|
+
# params which mustn't be copying to nested links
|
7
|
+
NESTED_PARAMS = %i[eid embedded association parent_scaffold].freeze
|
8
|
+
|
9
|
+
def skip_action_link?(link, *args)
|
10
|
+
!link.ignore_method.nil? && controller.respond_to?(link.ignore_method, true) && controller.send(link.ignore_method, *args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def action_link_authorized?(link, *args)
|
14
|
+
auth, reason =
|
15
|
+
if link.security_method_set? || controller.respond_to?(link.security_method, true)
|
16
|
+
controller.send(link.security_method, *args)
|
17
|
+
else
|
18
|
+
args.empty? ? true : args.first.authorized_for?(:crud_type => link.crud_type, :action => link.action, :reason => true)
|
19
|
+
end
|
20
|
+
[auth, reason]
|
21
|
+
end
|
22
|
+
|
23
|
+
def display_dynamic_action_group(action_link, links, record_or_ul_options = nil, ul_options = nil)
|
24
|
+
ul_options = record_or_ul_options if ul_options.nil? && record_or_ul_options.is_a?(Hash)
|
25
|
+
record = record_or_ul_options unless record_or_ul_options.is_a?(Hash)
|
26
|
+
html = content_tag :ul, ul_options do
|
27
|
+
safe_join links.map { |link| content_tag :li, link }
|
28
|
+
end
|
29
|
+
raw "ActiveScaffold.display_dynamic_action_group('#{get_action_link_id action_link, record}', '#{escape_javascript html}');"
|
30
|
+
end
|
31
|
+
|
32
|
+
def display_action_links(action_links, record, options, &block)
|
33
|
+
options[:level_0_tag] ||= nil
|
34
|
+
options[:options_level_0_tag] ||= nil
|
35
|
+
options[:level] ||= 0
|
36
|
+
options[:first_action] = true
|
37
|
+
output = ActiveSupport::SafeBuffer.new
|
38
|
+
|
39
|
+
action_links.each(:reverse => options.delete(:reverse), :groups => true) do |link|
|
40
|
+
if link.is_a? ActiveScaffold::DataStructures::ActionLinks
|
41
|
+
unless link.empty?
|
42
|
+
options[:level] += 1
|
43
|
+
content = display_action_links(link, record, options, &block)
|
44
|
+
options[:level] -= 1
|
45
|
+
if content.present?
|
46
|
+
output << display_action_link(link, content, record, options)
|
47
|
+
options[:first_action] = false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
elsif !skip_action_link?(link, *Array(options[:for]))
|
51
|
+
authorized, reason = action_link_authorized?(link, *Array(options[:for]))
|
52
|
+
next if !authorized && options[:skip_unauthorized]
|
53
|
+
output << display_action_link(link, nil, record, options.merge(:authorized => authorized, :not_authorized_reason => reason))
|
54
|
+
options[:first_action] = false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
output
|
58
|
+
end
|
59
|
+
|
60
|
+
def display_action_link(link, content, record, options)
|
61
|
+
if content
|
62
|
+
html_classes = hover_via_click? ? 'hover_click ' : ''
|
63
|
+
if (options[:level]).zero?
|
64
|
+
html_classes << 'action_group'
|
65
|
+
group_tag = :div
|
66
|
+
else
|
67
|
+
html_classes << 'top' if options[:first_action]
|
68
|
+
group_tag = :li
|
69
|
+
end
|
70
|
+
content = content_tag(group_tag, :class => (html_classes if html_classes.present?), :onclick => ('' if hover_via_click?)) do
|
71
|
+
content_tag(:div, as_(link.label), :class => link.name.to_s.downcase) << content_tag(:ul, content)
|
72
|
+
end
|
73
|
+
else
|
74
|
+
content = render_action_link(link, record, options)
|
75
|
+
content = content_tag(:li, content, :class => ('top' if options[:first_action])) unless (options[:level]).zero?
|
76
|
+
end
|
77
|
+
content = content_tag(options[:level_0_tag], content, options[:options_level_0_tag]) if (options[:level]).zero? && options[:level_0_tag]
|
78
|
+
content
|
79
|
+
end
|
80
|
+
|
81
|
+
def render_action_link(link, record = nil, options = {})
|
82
|
+
if link.action.nil? || link.column.try(:association).try(:polymorphic?)
|
83
|
+
link = action_link_to_inline_form(link, record) if link.column.try(:association)
|
84
|
+
options[:authorized] = false if link.action.nil? || link.controller.nil?
|
85
|
+
options.delete :link if link.crud_type == :create
|
86
|
+
end
|
87
|
+
if link.action.nil? || (link.type == :member && options.key?(:authorized) && !options[:authorized])
|
88
|
+
action_link_html(link, nil, {:link => action_link_text(link, options), :class => "disabled #{link.action}#{" #{link.html_options[:class]}" if link.html_options[:class].present?}", :title => options[:not_authorized_reason]}, record)
|
89
|
+
else
|
90
|
+
url = action_link_url(link, record)
|
91
|
+
html_options = action_link_html_options(link, record, options)
|
92
|
+
action_link_html(link, url, html_options, record)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# setup the action link to inline form
|
97
|
+
def action_link_to_inline_form(link, record)
|
98
|
+
link = link.clone
|
99
|
+
associated = record.send(link.column.association.name)
|
100
|
+
if link.column.association.try(:polymorphic?)
|
101
|
+
link.controller = controller_path_for_activerecord(associated.class)
|
102
|
+
return link if link.controller.nil?
|
103
|
+
end
|
104
|
+
link = configure_column_link(link, record, associated) if link.action.nil?
|
105
|
+
link
|
106
|
+
end
|
107
|
+
|
108
|
+
def configure_column_link(link, record, associated, actions = nil)
|
109
|
+
actions ||= link.column.actions_for_association_links
|
110
|
+
if column_empty?(associated) # if association is empty, we only can link to create form
|
111
|
+
if actions.include?(:new)
|
112
|
+
link.action = 'new'
|
113
|
+
link.crud_type = :create
|
114
|
+
link.label ||= as_(:create_new)
|
115
|
+
end
|
116
|
+
elsif actions.include?(:edit)
|
117
|
+
link.action = 'edit'
|
118
|
+
link.crud_type = :update
|
119
|
+
elsif actions.include?(:show)
|
120
|
+
link.action = 'show'
|
121
|
+
link.crud_type = :read
|
122
|
+
elsif actions.include?(:list)
|
123
|
+
link.action = 'index'
|
124
|
+
link.crud_type = :read
|
125
|
+
end
|
126
|
+
|
127
|
+
unless column_link_authorized?(link, link.column, record, associated)[0]
|
128
|
+
link.action = nil
|
129
|
+
# if action is edit and is not authorized, fallback to show if it's enabled
|
130
|
+
if link.crud_type == :update && actions.include?(:show)
|
131
|
+
link = configure_column_link(link, record, associated, [:show])
|
132
|
+
end
|
133
|
+
end
|
134
|
+
link
|
135
|
+
end
|
136
|
+
|
137
|
+
def column_link_authorized?(link, column, record, associated)
|
138
|
+
if column.association
|
139
|
+
associated_for_authorized =
|
140
|
+
if column.association.collection? || (associated.respond_to?(:blank?) && associated.blank?)
|
141
|
+
column.association.klass
|
142
|
+
else
|
143
|
+
associated
|
144
|
+
end
|
145
|
+
authorized, reason = associated_for_authorized.authorized_for?(:crud_type => link.crud_type, :reason => true)
|
146
|
+
if link.crud_type == :create && authorized
|
147
|
+
authorized, reason = record.authorized_for?(:crud_type => :update, :column => column.name, :reason => true)
|
148
|
+
end
|
149
|
+
[authorized, reason]
|
150
|
+
else
|
151
|
+
action_link_authorized?(link, record)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def sti_record?(record)
|
156
|
+
return unless active_scaffold_config.active_record?
|
157
|
+
model = active_scaffold_config.model
|
158
|
+
record && model.columns_hash.include?(model.inheritance_column) &&
|
159
|
+
record[model.inheritance_column].present? && !record.instance_of?(model)
|
160
|
+
end
|
161
|
+
|
162
|
+
def cache_action_link_url?(link, record)
|
163
|
+
active_scaffold_config.cache_action_link_urls && link.type == :member && !link.dynamic_parameters.is_a?(Proc) && !sti_record?(record)
|
164
|
+
end
|
165
|
+
|
166
|
+
def cached_action_link_url(link, record)
|
167
|
+
@action_links_urls ||= {}
|
168
|
+
@action_links_urls[link.name_to_cache] || begin
|
169
|
+
url_options = cached_action_link_url_options(link, record)
|
170
|
+
if cache_action_link_url?(link, record)
|
171
|
+
@action_links_urls[link.name_to_cache] = url_for(url_options)
|
172
|
+
else
|
173
|
+
url_options.merge! eid: nil, embedded: nil if link.nested_link?
|
174
|
+
url_for(params_for(url_options))
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def replace_id_params_in_action_link_url(link, record, url)
|
180
|
+
url = record ? url.sub('--ID--', record.to_param.to_s) : url.clone
|
181
|
+
if link.column.try(:association).try(:singular?)
|
182
|
+
child_id = record.send(link.column.association.name).try(:to_param)
|
183
|
+
if child_id.present?
|
184
|
+
url.sub!('--CHILD_ID--', child_id)
|
185
|
+
else
|
186
|
+
url.sub!(/\w+=--CHILD_ID--&?/, '')
|
187
|
+
url.sub!(/\?$/, '')
|
188
|
+
end
|
189
|
+
elsif nested?
|
190
|
+
url.sub!('--CHILD_ID--', params[nested.param_name].to_s)
|
191
|
+
end
|
192
|
+
url
|
193
|
+
end
|
194
|
+
|
195
|
+
def add_query_string_to_cached_url(link, url)
|
196
|
+
query_string, non_nested_query_string = query_string_for_action_links(link)
|
197
|
+
nested_params = (!link.nested_link? && non_nested_query_string)
|
198
|
+
if query_string || nested_params
|
199
|
+
url << (url.include?('?') ? '&' : '?')
|
200
|
+
url << query_string if query_string
|
201
|
+
url << non_nested_query_string if nested_params
|
202
|
+
end
|
203
|
+
url
|
204
|
+
end
|
205
|
+
|
206
|
+
def action_link_url(link, record)
|
207
|
+
url = replace_id_params_in_action_link_url(link, record, cached_action_link_url(link, record))
|
208
|
+
url = add_query_string_to_cached_url(link, url) if @action_links_urls[link.name_to_cache]
|
209
|
+
url
|
210
|
+
end
|
211
|
+
|
212
|
+
def query_string_for_action_links(link)
|
213
|
+
if defined?(@query_string) && link.parameters.none? { |k, _| @query_string_params.include? k }
|
214
|
+
return [@query_string, @non_nested_query_string]
|
215
|
+
end
|
216
|
+
keep = true
|
217
|
+
@query_string_params ||= Set.new
|
218
|
+
query_string_options = {}
|
219
|
+
non_nested_query_string_options = {}
|
220
|
+
|
221
|
+
params_for.except(:controller, :action, :id).each do |key, value|
|
222
|
+
@query_string_params << key
|
223
|
+
if link.parameters.include? key
|
224
|
+
keep = false
|
225
|
+
next
|
226
|
+
end
|
227
|
+
if NESTED_PARAMS.include?(key) || conditions_from_params.include?(key) || (nested? && nested.param_name == key)
|
228
|
+
non_nested_query_string_options[key] = value
|
229
|
+
else
|
230
|
+
query_string_options[key] = value
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
query_string = query_string_options.to_query if query_string_options.present?
|
235
|
+
if non_nested_query_string_options.present?
|
236
|
+
non_nested_query_string = "#{'&' if query_string}#{non_nested_query_string_options.to_query}"
|
237
|
+
end
|
238
|
+
if keep
|
239
|
+
@query_string = query_string
|
240
|
+
@non_nested_query_string = non_nested_query_string
|
241
|
+
end
|
242
|
+
[query_string, non_nested_query_string]
|
243
|
+
end
|
244
|
+
|
245
|
+
def cache_action_link_url_options?(link, record)
|
246
|
+
active_scaffold_config.cache_action_link_urls && (link.type == :collection || !link.dynamic_parameters.is_a?(Proc)) && !sti_record?(record)
|
247
|
+
end
|
248
|
+
|
249
|
+
def cached_action_link_url_options(link, record)
|
250
|
+
@action_links_url_options ||= {}
|
251
|
+
@action_links_url_options[link.name_to_cache] || begin
|
252
|
+
options = action_link_url_options(link, record)
|
253
|
+
if cache_action_link_url_options?(link, record)
|
254
|
+
@action_links_url_options[link.name_to_cache] = options
|
255
|
+
end
|
256
|
+
options
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def action_link_url_options(link, record)
|
261
|
+
url_options = {:action => link.action}
|
262
|
+
url_options[:id] = '--ID--' unless record.nil?
|
263
|
+
url_options[:controller] = link.controller.to_s if link.controller
|
264
|
+
url_options.merge! link.parameters if link.parameters
|
265
|
+
if link.dynamic_parameters.is_a?(Proc)
|
266
|
+
if record.nil?
|
267
|
+
url_options.merge! instance_exec(&link.dynamic_parameters)
|
268
|
+
else
|
269
|
+
url_options.merge! instance_exec(record, &link.dynamic_parameters)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
if link.nested_link?
|
273
|
+
url_options_for_nested_link(link.column, record, link, url_options)
|
274
|
+
elsif nested?
|
275
|
+
url_options[nested.param_name] = '--CHILD_ID--'
|
276
|
+
end
|
277
|
+
url_options_for_sti_link(link.column, record, link, url_options) unless record.nil? || active_scaffold_config.sti_children.nil?
|
278
|
+
url_options[:_method] = link.method if !link.confirm? && link.inline? && link.method != :get
|
279
|
+
url_options
|
280
|
+
end
|
281
|
+
|
282
|
+
def action_link_text(link, options)
|
283
|
+
text = image_tag(link.image[:name], :size => link.image[:size], :alt => options[:link] || link.label, :title => options[:link] || link.label) if link.image
|
284
|
+
text || options[:link]
|
285
|
+
end
|
286
|
+
|
287
|
+
def replaced_action_link_url_options(link, record)
|
288
|
+
url = cached_action_link_url_options(link, record)
|
289
|
+
url[:controller] ||= params[:controller]
|
290
|
+
missing_options, url_options = url.partition { |_, v| v.nil? }
|
291
|
+
replacements = {}
|
292
|
+
replacements['--ID--'] = record.id.to_s if record
|
293
|
+
if link.column.try(:association).try(:singular?)
|
294
|
+
replacements['--CHILD_ID--'] = record.send(link.column.association.name).try(:id).to_s
|
295
|
+
elsif nested?
|
296
|
+
replacements['--CHILD_ID--'] = params[nested.param_name].to_s
|
297
|
+
end
|
298
|
+
url_options.collect! do |k, v|
|
299
|
+
[k.to_s, replacements[v] || v]
|
300
|
+
end
|
301
|
+
[missing_options, url_options]
|
302
|
+
end
|
303
|
+
|
304
|
+
def action_link_selected?(link, record)
|
305
|
+
missing_options, url_options = replaced_action_link_url_options(link, record)
|
306
|
+
safe_params = (Rails.version < '4.2' ? params.to_h : params.to_unsafe_h)
|
307
|
+
(url_options - safe_params.to_a).blank? && missing_options.all? { |k, _| params[k].nil? }
|
308
|
+
end
|
309
|
+
|
310
|
+
def action_link_html_options(link, record, options)
|
311
|
+
link_id = get_action_link_id(link, record)
|
312
|
+
html_options = link.html_options.merge(:class => [link.html_options[:class], link.action.to_s].compact.join(' '))
|
313
|
+
html_options[:link] = action_link_text(link, options)
|
314
|
+
|
315
|
+
# Needs to be in html_options to as the adding _method to the url is no longer supported by Rails
|
316
|
+
html_options[:method] = link.method if link.method != :get
|
317
|
+
|
318
|
+
html_options[:data] ||= {}
|
319
|
+
html_options[:data][:confirm] = link.confirm(h(record.try(:to_label))) if link.confirm?
|
320
|
+
if !options[:page] && !options[:popup] && (options[:inline] || link.inline?)
|
321
|
+
html_options[:class] << ' as_action'
|
322
|
+
html_options[:data][:position] = link.position if link.position
|
323
|
+
html_options[:data][:action] = link.action
|
324
|
+
html_options[:data][:cancel_refresh] = true if link.refresh_on_close
|
325
|
+
html_options[:data][:keep_open] = true if link.keep_open?
|
326
|
+
html_options[:remote] = true
|
327
|
+
end
|
328
|
+
|
329
|
+
if link.toggle
|
330
|
+
html_options[:class] << ' toggle'
|
331
|
+
html_options[:class] << ' active' if action_link_selected?(link, record)
|
332
|
+
end
|
333
|
+
|
334
|
+
html_options[:target] = '_blank' if !options[:page] && !options[:inline] && (options[:popup] || link.popup?)
|
335
|
+
html_options[:id] = link_id
|
336
|
+
if link.dhtml_confirm?
|
337
|
+
unless link.inline?
|
338
|
+
html_options[:class] << ' as_action'
|
339
|
+
html_options[:page_link] = 'true'
|
340
|
+
end
|
341
|
+
html_options[:dhtml_confirm] = link.dhtml_confirm.value
|
342
|
+
html_options[:onclick] = link.dhtml_confirm.onclick_function(controller, link_id)
|
343
|
+
end
|
344
|
+
html_options
|
345
|
+
end
|
346
|
+
|
347
|
+
def get_action_link_id(link, record = nil, column = nil)
|
348
|
+
column ||= link.column
|
349
|
+
if column.try(:association) && record
|
350
|
+
id = if column.association.collection?
|
351
|
+
"#{column.association.name}-#{record.id}"
|
352
|
+
elsif record.send(column.association.name).present?
|
353
|
+
"#{column.association.name}-#{record.send(column.association.name).id}-#{record.id}"
|
354
|
+
else
|
355
|
+
"#{column.association.name}-#{record.id}"
|
356
|
+
end
|
357
|
+
end
|
358
|
+
id ||= record.try(:id) || (nested? ? nested_parent_id : '')
|
359
|
+
action_id = "#{id_from_controller("#{link.controller}-") if params[:parent_controller] || (link.controller && link.controller != controller.controller_path)}#{link.action}"
|
360
|
+
action_link_id(action_id, id)
|
361
|
+
end
|
362
|
+
|
363
|
+
def action_link_html(link, url, html_options, record)
|
364
|
+
label = html_options.delete(:link)
|
365
|
+
label ||= link.label
|
366
|
+
if url.nil?
|
367
|
+
content_tag(:a, label, html_options)
|
368
|
+
else
|
369
|
+
link_to(label, url, html_options)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
def url_options_for_nested_link(column, record, link, url_options)
|
374
|
+
if column.try(:association)
|
375
|
+
url_options[:parent_scaffold] = controller_path
|
376
|
+
url_options[column.model.name.foreign_key.to_sym] = url_options.delete(:id)
|
377
|
+
url_options[:id] = if column.association.singular? && url_options[:action].to_sym != :index
|
378
|
+
'--CHILD_ID--'
|
379
|
+
end
|
380
|
+
elsif link.parameters && link.parameters[:named_scope]
|
381
|
+
url_options[:parent_scaffold] = controller_path
|
382
|
+
url_options[active_scaffold_config.model.name.foreign_key.to_sym] = url_options.delete(:id)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
def url_options_for_sti_link(column, record, link, url_options)
|
387
|
+
# need to find out controller of current record type and set parameters
|
388
|
+
# it's quite difficult to detect an sti link
|
389
|
+
# if link.column.nil? we are sure that it isn't a singular association inline autolink
|
390
|
+
# however that will not work if a sti parent is a singular association inline autolink
|
391
|
+
return unless link.column.nil?
|
392
|
+
return if (sti_controller_path = controller_path_for_activerecord(record.class)).nil?
|
393
|
+
url_options[:controller] = sti_controller_path
|
394
|
+
url_options[:parent_sti] = controller_path
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
@@ -5,7 +5,7 @@ module ActiveScaffold
|
|
5
5
|
def cache_association_options(association, conditions, klass, cache = true)
|
6
6
|
if active_scaffold_config.cache_association_options && cache
|
7
7
|
@_associations_cache ||= Hash.new { |h, k| h[k] = {} }
|
8
|
-
key = [association.name, association.
|
8
|
+
key = [association.name, association.inverse_klass.name, klass.name].join('/')
|
9
9
|
@_associations_cache[key][conditions] ||= yield
|
10
10
|
else
|
11
11
|
yield
|
@@ -14,10 +14,8 @@ module ActiveScaffold
|
|
14
14
|
|
15
15
|
# Provides a way to honor the :conditions on an association while searching the association's klass
|
16
16
|
def association_options_find(association, conditions = nil, klass = nil, record = nil)
|
17
|
-
|
18
|
-
|
19
|
-
if klass.nil? && association.options[:polymorphic]
|
20
|
-
class_name = record.send(association.foreign_type)
|
17
|
+
if klass.nil? && association.polymorphic?
|
18
|
+
class_name = record.send(association.foreign_type) if association.belongs_to?
|
21
19
|
if class_name.present?
|
22
20
|
klass = class_name.constantize
|
23
21
|
else
|
@@ -29,18 +27,10 @@ module ActiveScaffold
|
|
29
27
|
klass ||= association.klass
|
30
28
|
end
|
31
29
|
|
32
|
-
|
33
|
-
if method(:options_for_association_conditions).arity.abs == 2
|
34
|
-
conditions = options_for_association_conditions(association, record)
|
35
|
-
else
|
36
|
-
ActiveSupport::Deprecation.warn 'Relying on @record is deprecated, include record in your options_for_association_conditions overrided method.', caller if record.nil? # TODO: Remove when relying on @record is removed
|
37
|
-
conditions = options_for_association_conditions(association)
|
38
|
-
end
|
39
|
-
end
|
30
|
+
conditions ||= options_for_association_conditions(association, record)
|
40
31
|
cache_association_options(association, conditions, klass, cache) do
|
41
32
|
klass = association_klass_scoped(association, klass, record)
|
42
|
-
relation = klass.where(conditions)
|
43
|
-
relation = relation.includes(association.options[:include]) if association.options[:include]
|
33
|
+
relation = klass.where(conditions)
|
44
34
|
column = column_for_association(association, record)
|
45
35
|
if column && column.try(:sort) && column.sort[:sql]
|
46
36
|
if column.includes
|
@@ -60,6 +50,7 @@ module ActiveScaffold
|
|
60
50
|
|
61
51
|
def association_klass_scoped(association, klass, record)
|
62
52
|
if nested? && nested.through_association? && nested.child_association.try(:through_reflection) == association
|
53
|
+
# only ActiveRecord associations
|
63
54
|
if nested.association.through_reflection.collection?
|
64
55
|
nested_parent_record.send(nested.association.through_reflection.name)
|
65
56
|
else
|
@@ -82,16 +73,11 @@ module ActiveScaffold
|
|
82
73
|
end
|
83
74
|
|
84
75
|
def association_options_count(association, conditions = nil)
|
85
|
-
association.klass.where(conditions).
|
76
|
+
association.klass.where(conditions).count
|
86
77
|
end
|
87
78
|
|
88
79
|
def options_for_association_count(association, record)
|
89
|
-
|
90
|
-
conditions = options_for_association_conditions(association, record)
|
91
|
-
else
|
92
|
-
ActiveSupport::Deprecation.warn 'Relying on @record is deprecated, include record in your options_for_association_conditions overrided method.', caller if record.nil? # TODO: Remove when relying on @record is removed
|
93
|
-
conditions = options_for_association_conditions(association)
|
94
|
-
end
|
80
|
+
conditions = options_for_association_conditions(association, record)
|
95
81
|
association_options_count(association, conditions)
|
96
82
|
end
|
97
83
|
|
@@ -99,14 +85,10 @@ module ActiveScaffold
|
|
99
85
|
# Should work in both the subform and form_ui=>:select modes.
|
100
86
|
# Check association.name to specialize the conditions per-column.
|
101
87
|
def options_for_association_conditions(association, record = nil)
|
102
|
-
return nil if association.
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
{association.foreign_key => nil}
|
107
|
-
when :belongs_to, :has_and_belongs_to_many
|
108
|
-
# Find all
|
109
|
-
nil
|
88
|
+
return nil if association.through?
|
89
|
+
if association.has_one? || association.has_many?
|
90
|
+
# Find only orphaned objects
|
91
|
+
{association.foreign_key => nil}
|
110
92
|
end
|
111
93
|
end
|
112
94
|
|