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.
Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +39 -0
  3. data/{LICENSE → LICENSE.md} +1 -1
  4. data/README.md +27 -19
  5. data/app/assets/javascripts/active_scaffold.js.erb +1 -1
  6. data/app/assets/javascripts/jquery/active_scaffold.js +95 -43
  7. data/app/assets/javascripts/jquery/tiny_mce_bridge.js +30 -6
  8. data/app/assets/javascripts/prototype/tiny_mce_bridge.js +11 -1
  9. data/app/assets/stylesheets/active_scaffold_colors.scss +2 -2
  10. data/app/assets/stylesheets/active_scaffold_layout.css +36 -28
  11. data/app/views/active_scaffold_overrides/_base_form.html.erb +2 -3
  12. data/app/views/active_scaffold_overrides/_field_search.html.erb +8 -7
  13. data/app/views/active_scaffold_overrides/_form_association.html.erb +9 -9
  14. data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +6 -6
  15. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +52 -50
  16. data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +1 -1
  17. data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +1 -1
  18. data/app/views/active_scaffold_overrides/_human_conditions.html.erb +3 -1
  19. data/app/views/active_scaffold_overrides/_list_calculations.html.erb +1 -1
  20. data/app/views/active_scaffold_overrides/_list_column_headings.html.erb +2 -0
  21. data/app/views/active_scaffold_overrides/_list_messages.html.erb +5 -3
  22. data/app/views/active_scaffold_overrides/_list_record.html.erb +3 -1
  23. data/app/views/active_scaffold_overrides/_list_with_header.html.erb +9 -9
  24. data/app/views/active_scaffold_overrides/_messages.html.erb +1 -1
  25. data/app/views/active_scaffold_overrides/_refresh_list.js.erb +18 -10
  26. data/app/views/active_scaffold_overrides/_render_field.js.erb +3 -3
  27. data/app/views/active_scaffold_overrides/_search.html.erb +7 -6
  28. data/app/views/active_scaffold_overrides/_show_actions.html.erb +14 -0
  29. data/app/views/active_scaffold_overrides/_show_association.html.erb +1 -1
  30. data/app/views/active_scaffold_overrides/_update_actions.html.erb +6 -2
  31. data/app/views/active_scaffold_overrides/_update_column.js.erb +1 -1
  32. data/app/views/active_scaffold_overrides/_update_form.html.erb +1 -1
  33. data/app/views/active_scaffold_overrides/destroy.js.erb +2 -3
  34. data/app/views/active_scaffold_overrides/edit_associated.js.erb +4 -3
  35. data/app/views/active_scaffold_overrides/on_action_update.js.erb +5 -3
  36. data/app/views/active_scaffold_overrides/on_create.js.erb +4 -4
  37. data/app/views/active_scaffold_overrides/on_update.js.erb +6 -6
  38. data/app/views/active_scaffold_overrides/show.html.erb +6 -0
  39. data/app/views/active_scaffold_overrides/update.html.erb +1 -1
  40. data/app/views/active_scaffold_overrides/update_column.js.erb +1 -1
  41. data/config/brakeman.ignore +26 -0
  42. data/config/brakeman.yml +3 -0
  43. data/config/i18n-tasks.yml +121 -0
  44. data/config/locales/de.yml +81 -70
  45. data/config/locales/en.yml +83 -74
  46. data/config/locales/es.yml +82 -73
  47. data/config/locales/fr.yml +86 -75
  48. data/config/locales/hu.yml +81 -70
  49. data/config/locales/ja.yml +71 -60
  50. data/config/locales/ru.yml +85 -74
  51. data/lib/active_scaffold.rb +3 -0
  52. data/lib/active_scaffold/actions/common_search.rb +11 -7
  53. data/lib/active_scaffold/actions/core.rb +119 -47
  54. data/lib/active_scaffold/actions/create.rb +1 -1
  55. data/lib/active_scaffold/actions/delete.rb +11 -8
  56. data/lib/active_scaffold/actions/field_search.rb +104 -6
  57. data/lib/active_scaffold/actions/list.rb +25 -21
  58. data/lib/active_scaffold/actions/mark.rb +12 -4
  59. data/lib/active_scaffold/actions/nested.rb +26 -26
  60. data/lib/active_scaffold/actions/search.rb +2 -2
  61. data/lib/active_scaffold/actions/show.rb +4 -5
  62. data/lib/active_scaffold/actions/subform.rb +9 -7
  63. data/lib/active_scaffold/actions/update.rb +20 -13
  64. data/lib/active_scaffold/active_record_permissions.rb +24 -5
  65. data/lib/active_scaffold/attribute_params.rb +68 -49
  66. data/lib/active_scaffold/bridges.rb +1 -1
  67. data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +15 -19
  68. data/lib/active_scaffold/bridges/bitfields.rb +1 -1
  69. data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +10 -14
  70. data/lib/active_scaffold/bridges/calendar_date_select.rb +0 -7
  71. data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +19 -22
  72. data/lib/active_scaffold/bridges/cancan.rb +4 -3
  73. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +11 -21
  74. data/lib/active_scaffold/bridges/carrierwave.rb +2 -1
  75. data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +2 -6
  76. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +6 -39
  77. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
  78. data/lib/active_scaffold/bridges/chosen.rb +4 -1
  79. data/lib/active_scaffold/bridges/chosen/helpers.rb +3 -2
  80. data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +2 -2
  81. data/lib/active_scaffold/bridges/date_picker.rb +3 -0
  82. data/lib/active_scaffold/bridges/date_picker/ext.rb +43 -38
  83. data/lib/active_scaffold/bridges/date_picker/helper.rb +24 -23
  84. data/lib/active_scaffold/bridges/dragonfly.rb +1 -1
  85. data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +3 -7
  86. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -25
  87. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +2 -2
  88. data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +6 -8
  89. data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +1 -1
  90. data/lib/active_scaffold/bridges/file_column/form_ui.rb +0 -2
  91. data/lib/active_scaffold/bridges/file_column/list_ui.rb +2 -1
  92. data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +1 -1
  93. data/lib/active_scaffold/bridges/paper_trail/actions.rb +1 -1
  94. data/lib/active_scaffold/bridges/paper_trail/helper.rb +1 -2
  95. data/lib/active_scaffold/bridges/paper_trail/paper_trail_bridge.rb +3 -7
  96. data/lib/active_scaffold/bridges/paperclip.rb +1 -1
  97. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -28
  98. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
  99. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +3 -7
  100. data/lib/active_scaffold/bridges/record_select.rb +2 -0
  101. data/lib/active_scaffold/bridges/record_select/helpers.rb +14 -18
  102. data/lib/active_scaffold/bridges/semantic_attributes/column.rb +4 -8
  103. data/lib/active_scaffold/bridges/shared/date_bridge.rb +20 -20
  104. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +7 -22
  105. data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +14 -14
  106. data/lib/active_scaffold/config/base.rb +9 -6
  107. data/lib/active_scaffold/config/core.rb +30 -21
  108. data/lib/active_scaffold/config/create.rb +2 -1
  109. data/lib/active_scaffold/config/delete.rb +2 -2
  110. data/lib/active_scaffold/config/field_search.rb +9 -3
  111. data/lib/active_scaffold/config/form.rb +4 -4
  112. data/lib/active_scaffold/config/list.rb +27 -23
  113. data/lib/active_scaffold/config/nested.rb +4 -4
  114. data/lib/active_scaffold/config/search.rb +6 -6
  115. data/lib/active_scaffold/config/show.rb +11 -1
  116. data/lib/active_scaffold/config/subform.rb +1 -1
  117. data/lib/active_scaffold/config/update.rb +4 -2
  118. data/lib/active_scaffold/constraints.rb +39 -36
  119. data/lib/active_scaffold/core.rb +36 -15
  120. data/lib/active_scaffold/data_structures/action_columns.rb +14 -9
  121. data/lib/active_scaffold/data_structures/action_link.rb +4 -5
  122. data/lib/active_scaffold/data_structures/action_links.rb +5 -4
  123. data/lib/active_scaffold/data_structures/actions.rb +2 -2
  124. data/lib/active_scaffold/data_structures/association.rb +8 -0
  125. data/lib/active_scaffold/data_structures/association/abstract.rb +147 -0
  126. data/lib/active_scaffold/data_structures/association/active_mongoid.rb +42 -0
  127. data/lib/active_scaffold/data_structures/association/active_record.rb +94 -0
  128. data/lib/active_scaffold/data_structures/association/mongoid.rb +45 -0
  129. data/lib/active_scaffold/data_structures/bridge.rb +3 -6
  130. data/lib/active_scaffold/data_structures/column.rb +100 -82
  131. data/lib/active_scaffold/data_structures/columns.rb +21 -3
  132. data/lib/active_scaffold/data_structures/nested_info.rb +22 -37
  133. data/lib/active_scaffold/data_structures/set.rb +4 -4
  134. data/lib/active_scaffold/data_structures/sorting.rb +29 -15
  135. data/lib/active_scaffold/engine.rb +3 -1
  136. data/lib/active_scaffold/extensions/action_controller_rendering.rb +10 -5
  137. data/lib/active_scaffold/extensions/action_view_rendering.rb +65 -59
  138. data/lib/active_scaffold/extensions/left_outer_joins.rb +48 -53
  139. data/lib/active_scaffold/extensions/localize.rb +3 -4
  140. data/lib/active_scaffold/extensions/name_option_for_datetime.rb +7 -11
  141. data/lib/active_scaffold/extensions/paginator_extensions.rb +20 -18
  142. data/lib/active_scaffold/extensions/routing_mapper.rb +104 -40
  143. data/lib/active_scaffold/extensions/to_label.rb +1 -1
  144. data/lib/active_scaffold/extensions/unsaved_associated.rb +4 -13
  145. data/lib/active_scaffold/extensions/unsaved_record.rb +12 -1
  146. data/lib/active_scaffold/finder.rb +200 -134
  147. data/lib/active_scaffold/helpers/action_link_helpers.rb +398 -0
  148. data/lib/active_scaffold/helpers/association_helpers.rb +12 -30
  149. data/lib/active_scaffold/helpers/controller_helpers.rb +74 -24
  150. data/lib/active_scaffold/helpers/form_column_helpers.rb +205 -112
  151. data/lib/active_scaffold/helpers/human_condition_helpers.rb +21 -11
  152. data/lib/active_scaffold/helpers/id_helpers.rb +1 -1
  153. data/lib/active_scaffold/helpers/list_column_helpers.rb +117 -39
  154. data/lib/active_scaffold/helpers/pagination_helpers.rb +11 -14
  155. data/lib/active_scaffold/helpers/search_column_helpers.rb +69 -32
  156. data/lib/active_scaffold/helpers/show_column_helpers.rb +9 -3
  157. data/lib/active_scaffold/helpers/view_helpers.rb +41 -426
  158. data/lib/active_scaffold/orm_checks.rb +109 -0
  159. data/lib/active_scaffold/paginator.rb +1 -1
  160. data/lib/active_scaffold/responds_to_parent.rb +12 -10
  161. data/lib/active_scaffold/tableless.rb +81 -43
  162. data/lib/active_scaffold/version.rb +2 -2
  163. data/lib/generators/active_scaffold/controller_generator.rb +49 -0
  164. data/lib/generators/active_scaffold/install_generator.rb +45 -0
  165. data/lib/generators/active_scaffold/resource_generator.rb +56 -0
  166. data/lib/generators/{active_scaffold_controller/templates → templates}/controller.rb +0 -0
  167. data/lib/generators/{active_scaffold_controller/templates → templates}/helper.rb +0 -0
  168. data/shoulda_macros/macros.rb +3 -3
  169. data/test/active_scaffold_config_mock.rb +33 -0
  170. data/test/bridges/bridge_test.rb +9 -9
  171. data/test/bridges/date_picker_test.rb +3 -1
  172. data/test/bridges/paper_trail_test.rb +2 -3
  173. data/test/bridges/paperclip_test.rb +21 -10
  174. data/test/bridges/tiny_mce_test.rb +20 -21
  175. data/test/class_with_finder.rb +42 -0
  176. data/test/company.rb +6 -4
  177. data/test/config/core_test.rb +1 -1
  178. data/test/config/create_test.rb +1 -1
  179. data/test/config/list_test.rb +3 -3
  180. data/test/config/update_test.rb +3 -3
  181. data/test/data_structures/action_columns_test.rb +3 -3
  182. data/test/data_structures/association_column_test.rb +5 -5
  183. data/test/data_structures/column_test.rb +14 -14
  184. data/test/data_structures/columns_test.rb +2 -2
  185. data/test/data_structures/set_test.rb +2 -2
  186. data/test/data_structures/sorting_test.rb +6 -4
  187. data/test/extensions/active_record_test.rb +1 -1
  188. data/test/extensions/routing_mapper_test.rb +64 -13
  189. data/test/helpers/form_column_helpers_test.rb +6 -6
  190. data/test/helpers/list_column_helpers_test.rb +9 -5
  191. data/test/helpers/pagination_helpers_test.rb +1 -0
  192. data/test/misc/active_record_permissions_test.rb +18 -1
  193. data/test/misc/attribute_params_test.rb +26 -17
  194. data/test/misc/calculation_test.rb +8 -31
  195. data/test/misc/configurable_test.rb +3 -2
  196. data/test/misc/constraints_test.rb +33 -22
  197. data/test/misc/convert_numbers_format_test.rb +28 -10
  198. data/test/misc/finder_test.rb +6 -29
  199. data/test/misc/parse_datetime_test.rb +160 -0
  200. data/test/misc/render_test.rb +1 -1
  201. data/test/misc/tableless_test.rb +24 -0
  202. data/test/mock_app/app/models/building.rb +2 -1
  203. data/test/mock_app/config.ru +1 -1
  204. data/test/mock_app/config/environments/test.rb +1 -1
  205. data/test/mock_app/config/routes.rb +11 -3
  206. data/test/model_stub.rb +11 -6
  207. data/test/run_all.rb +1 -1
  208. data/test/test_helper.rb +19 -4
  209. metadata +42 -23
  210. data/lib/active_scaffold/data_structures/error_message.rb +0 -22
  211. data/lib/active_scaffold/extensions/reverse_associations.rb +0 -119
  212. data/lib/generators/active_scaffold/USAGE +0 -29
  213. data/lib/generators/active_scaffold/active_scaffold_generator.rb +0 -21
  214. data/lib/generators/active_scaffold_controller/USAGE +0 -19
  215. data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +0 -29
  216. data/test/data_structures/error_message_test.rb +0 -25
@@ -3,18 +3,20 @@ module ActiveScaffold
3
3
  # Helpers that assist with the rendering of a List Column
4
4
  module ShowColumnHelpers
5
5
  def show_column_value(record, column)
6
+ value_record = column.delegated_association ? record.send(column.delegated_association.name) : record
7
+ return get_column_value(record, column) unless value_record
6
8
  # check for an override helper
7
9
  if (method = show_column_override(column))
8
10
  # we only pass the record as the argument. we previously also passed the formatted_value,
9
11
  # but mike perham pointed out that prohibited the usage of overrides to improve on the
10
12
  # performance of our default formatting. see issue #138.
11
- send(method, record, column)
13
+ send(method, value_record, column)
12
14
  # second, check if the dev has specified a valid list_ui for this column
13
15
  elsif column.show_ui && (method = override_show_column_ui(column.show_ui))
14
- send(method, record, column)
16
+ send(method, value_record, column)
15
17
  else
16
18
  if column.column && (method = override_show_column_ui(column.column.type))
17
- send(method, record, column)
19
+ send(method, value_record, column)
18
20
  else
19
21
  get_column_value(record, column)
20
22
  end
@@ -56,6 +58,10 @@ module ActiveScaffold
56
58
  method = "active_scaffold_show_#{show_ui}"
57
59
  method if respond_to? method
58
60
  end
61
+
62
+ def display_link_in_show?(link, position)
63
+ position == :header
64
+ end
59
65
  end
60
66
  end
61
67
  end
@@ -3,8 +3,8 @@ module ActiveScaffold
3
3
  # All extra helpers that should be included in the View.
4
4
  # Also a dumping ground for uncategorized helpers.
5
5
  module ViewHelpers
6
- NESTED_PARAMS = [:eid, :association, :parent_scaffold]
7
6
  include ActiveScaffold::Helpers::IdHelpers
7
+ include ActiveScaffold::Helpers::ActionLinkHelpers
8
8
  include ActiveScaffold::Helpers::AssociationHelpers
9
9
  include ActiveScaffold::Helpers::PaginationHelpers
10
10
  include ActiveScaffold::Helpers::ListColumnHelpers
@@ -44,16 +44,9 @@ module ActiveScaffold
44
44
  # This is the template finder logic, keep it updated with however we find stuff in rails
45
45
  # currently this very similar to the logic in ActionBase::Base.render for options file
46
46
  def template_exists?(template_name, partial = false)
47
- lookup_context.exists? template_name, '', partial
48
- end
49
-
50
- # Turns [[label, value]] into <option> tags
51
- # Takes optional parameter of :include_blank
52
- def option_tags_for(select_options, options = {})
53
- select_options.insert(0, [as_(:_select_), nil]) if options[:include_blank]
54
- select_options.collect do |option|
55
- label, value = option[0], option[1]
56
- value.nil? ? '<option value='">#{label}</option>" : "<option value=\"#{value}\">#{label}</option>"
47
+ restore_view_paths, lookup_context.view_paths = lookup_context.view_paths, @_view_paths if @_view_paths
48
+ lookup_context.exists?(template_name, '', partial).tap do
49
+ lookup_context.view_paths = restore_view_paths if @_view_paths
57
50
  end
58
51
  end
59
52
 
@@ -61,9 +54,10 @@ module ActiveScaffold
61
54
  options[:target] = action_iframe_id(url_for_options)
62
55
  options[:multipart] ||= true
63
56
  options[:class] = "#{options[:class]} as_remote_upload".strip
64
- output = ''
57
+ output = []
65
58
  output << form_tag(url_for_options, options)
66
- (output << "<iframe id='#{action_iframe_id(url_for_options)}' name='#{action_iframe_id(url_for_options)}' style='display:none'></iframe>").html_safe
59
+ output << content_tag(:iframe, '', id: action_iframe_id(url_for_options), name: action_iframe_id(url_for_options), style: 'display:none')
60
+ safe_join output
67
61
  end
68
62
 
69
63
  # a general-use loading indicator (the "stuff is happening, please wait" feedback)
@@ -81,389 +75,6 @@ module ActiveScaffold
81
75
  link_to options[:default_visible] ? options[:hide_label] : options[:show_label], '#', :data => {:show => options[:show_label], :hide => options[:hide_label], :toggable => id}, :style => 'display: none;', :class => 'as-js-button visibility-toggle'
82
76
  end
83
77
 
84
- def skip_action_link?(link, *args)
85
- !link.ignore_method.nil? && controller.respond_to?(link.ignore_method, true) && controller.send(link.ignore_method, *args)
86
- end
87
-
88
- def action_link_authorized?(link, *args)
89
- if link.security_method_set? || controller.respond_to?(link.security_method, true)
90
- controller.send(link.security_method, *args)
91
- else
92
- args.empty? ? true : args.first.authorized_for?(:crud_type => link.crud_type, :action => link.action)
93
- end
94
- end
95
-
96
- def display_dynamic_action_group(action_link, links, record_or_ul_options = nil, ul_options = nil)
97
- ul_options = record_or_ul_options if ul_options.nil? && record_or_ul_options.is_a?(Hash)
98
- record = record_or_ul_options unless record_or_ul_options.is_a?(Hash)
99
- html = content_tag :ul, ul_options do
100
- links.map { |link| content_tag :li, link }.join('').html_safe
101
- end
102
- raw "ActiveScaffold.display_dynamic_action_group('#{get_action_link_id action_link, record}', '#{escape_javascript html}');"
103
- end
104
-
105
- def display_action_links(action_links, record, options, &block)
106
- options[:level_0_tag] ||= nil
107
- options[:options_level_0_tag] ||= nil
108
- options[:level] ||= 0
109
- options[:first_action] = true
110
- output = ActiveSupport::SafeBuffer.new
111
-
112
- action_links.each(:reverse => options.delete(:reverse), :groups => true) do |link|
113
- if link.is_a? ActiveScaffold::DataStructures::ActionLinks
114
- unless link.empty?
115
- options[:level] += 1
116
- content = display_action_links(link, record, options, &block)
117
- options[:level] -= 1
118
- if content.present?
119
- output << display_action_link(link, content, record, options)
120
- options[:first_action] = false
121
- end
122
- end
123
- elsif !skip_action_link?(link, *Array(options[:for]))
124
- authorized = action_link_authorized?(link, *Array(options[:for]))
125
- next if !authorized && options[:skip_unauthorized]
126
- output << display_action_link(link, nil, record, options.merge(:authorized => authorized))
127
- options[:first_action] = false
128
- end
129
- end
130
- output
131
- end
132
-
133
- def display_action_link(link, content, record, options)
134
- if content
135
- html_classes = hover_via_click? ? 'hover_click ' : ''
136
- if options[:level] == 0
137
- html_classes << 'action_group'
138
- group_tag = :div
139
- else
140
- html_classes << 'top' if options[:first_action]
141
- group_tag = :li
142
- end
143
- content = content_tag(group_tag, :class => (html_classes if html_classes.present?), :onclick => ('' if hover_via_click?)) do
144
- content_tag(:div, as_(link.label), :class => link.name.to_s.downcase) << content_tag(:ul, content)
145
- end
146
- else
147
- content = render_action_link(link, record, options)
148
- content = content_tag(:li, content, :class => ('top' if options[:first_action])) unless options[:level] == 0
149
- end
150
- content = content_tag(options[:level_0_tag], content, options[:options_level_0_tag]) if options[:level] == 0 && options[:level_0_tag]
151
- content
152
- end
153
-
154
- def render_action_link(link, record = nil, options = {})
155
- if link.action.nil? || link.column.try(:polymorphic_association?)
156
- link = action_link_to_inline_form(link, record) if link.column.try(:association)
157
- options[:authorized] = false if link.action.nil? || link.controller.nil?
158
- options.delete :link if link.crud_type == :create
159
- end
160
- if link.action.nil? || (link.type == :member && options.key?(:authorized) && !options[:authorized])
161
- action_link_html(link, nil, {:link => action_link_text(link, options), :class => "disabled #{link.action}#{" #{link.html_options[:class]}" unless link.html_options[:class].blank?}"}, record)
162
- else
163
- url = action_link_url(link, record)
164
- html_options = action_link_html_options(link, record, options)
165
- action_link_html(link, url, html_options, record)
166
- end
167
- end
168
-
169
- # setup the action link to inline form
170
- def action_link_to_inline_form(link, record)
171
- link = link.clone
172
- associated = record.send(link.column.association.name)
173
- if link.column.polymorphic_association?
174
- link.controller = controller_path_for_activerecord(associated.class)
175
- return link if link.controller.nil?
176
- end
177
- link = configure_column_link(link, record, associated) if link.action.nil?
178
- link
179
- end
180
-
181
- def configure_column_link(link, record, associated, actions = nil)
182
- actions ||= link.column.actions_for_association_links
183
- if column_empty?(associated) # if association is empty, we only can link to create form
184
- if actions.include?(:new)
185
- link.action = 'new'
186
- link.crud_type = :create
187
- link.label ||= as_(:create_new)
188
- end
189
- elsif actions.include?(:edit)
190
- link.action = 'edit'
191
- link.crud_type = :update
192
- elsif actions.include?(:show)
193
- link.action = 'show'
194
- link.crud_type = :read
195
- elsif actions.include?(:list)
196
- link.action = 'index'
197
- link.crud_type = :read
198
- end
199
-
200
- unless column_link_authorized?(link, link.column, record, associated)
201
- link.action = nil
202
- # if action is edit and is not authorized, fallback to show if it's enabled
203
- if link.crud_type == :update && actions.include?(:show)
204
- link = configure_column_link(link, record, associated, [:show])
205
- end
206
- end
207
- link
208
- end
209
-
210
- def column_link_authorized?(link, column, record, associated)
211
- if column.association
212
- associated_for_authorized =
213
- if column.plural_association? || (associated.respond_to?(:blank?) && associated.blank?)
214
- column.association.klass
215
- else
216
- associated
217
- end
218
- authorized = associated_for_authorized.authorized_for?(:crud_type => link.crud_type)
219
- authorized &&= record.authorized_for?(:crud_type => :update, :column => column.name) if link.crud_type == :create
220
- authorized
221
- else
222
- action_link_authorized?(link, record)
223
- end
224
- end
225
-
226
- def is_sti_record?(record)
227
- model = active_scaffold_config.model
228
- record && model.columns_hash.include?(model.inheritance_column) &&
229
- record[model.inheritance_column].present? && !record.instance_of?(model)
230
- end
231
-
232
- def cache_action_link_url?(link, record)
233
- active_scaffold_config.cache_action_link_urls && link.type == :member && !link.dynamic_parameters.is_a?(Proc) && !is_sti_record?(record)
234
- end
235
-
236
- def cached_action_link_url(link, record)
237
- @action_links_urls ||= {}
238
- @action_links_urls[link.name_to_cache] || begin
239
- url_options = cached_action_link_url_options(link, record)
240
- if cache_action_link_url?(link, record)
241
- @action_links_urls[link.name_to_cache] = url_for(url_options)
242
- else
243
- url_for(params_for(url_options))
244
- end
245
- end
246
- end
247
-
248
- def replace_id_params_in_action_link_url(link, record, url)
249
- url = record ? url.sub('--ID--', record.to_param.to_s) : url.clone
250
- if link.column.try(:singular_association?)
251
- child_id = record.send(link.column.association.name).try(:to_param)
252
- if child_id.present?
253
- url.sub!('--CHILD_ID--', child_id)
254
- else
255
- url.sub!(/\w+=--CHILD_ID--&?/, '')
256
- url.sub!(/\?$/, '')
257
- end
258
- elsif nested?
259
- url.sub!('--CHILD_ID--', params[nested.param_name].to_s)
260
- end
261
- url
262
- end
263
-
264
- def add_query_string_to_cached_url(link, url)
265
- query_string, non_nested_query_string = query_string_for_action_links(link)
266
- nested_params = (!link.nested_link? && non_nested_query_string)
267
- if query_string || nested_params
268
- url << (url.include?('?') ? '&' : '?')
269
- url << query_string if query_string
270
- url << non_nested_query_string if nested_params
271
- end
272
- url
273
- end
274
-
275
- def action_link_url(link, record)
276
- url = replace_id_params_in_action_link_url(link, record, cached_action_link_url(link, record))
277
- url = add_query_string_to_cached_url(link, url) if @action_links_urls[link.name_to_cache]
278
- url
279
- end
280
-
281
- def query_string_for_action_links(link)
282
- if defined?(@query_string) && link.parameters.none? { |k, _| @query_string_params.include? k }
283
- return [@query_string, @non_nested_query_string]
284
- end
285
- keep = true
286
- @query_string_params ||= Set.new
287
- query_string_options = {}
288
- non_nested_query_string_options = {}
289
-
290
- params_for.except(:controller, :action, :id).each do |key, value|
291
- @query_string_params << key
292
- if link.parameters.include? key
293
- keep = false
294
- next
295
- end
296
- if NESTED_PARAMS.include?(key) || conditions_from_params.include?(key) || (nested? && nested.param_name == key)
297
- non_nested_query_string_options[key] = value
298
- else
299
- query_string_options[key] = value
300
- end
301
- end
302
-
303
- query_string = query_string_options.to_query if query_string_options.present?
304
- if non_nested_query_string_options.present?
305
- non_nested_query_string = "#{'&' if query_string}#{non_nested_query_string_options.to_query}"
306
- end
307
- if keep
308
- @query_string = query_string
309
- @non_nested_query_string = non_nested_query_string
310
- end
311
- [query_string, non_nested_query_string]
312
- end
313
-
314
- def cache_action_link_url_options?(link, record)
315
- active_scaffold_config.cache_action_link_urls && (link.type == :collection || !link.dynamic_parameters.is_a?(Proc)) && !is_sti_record?(record)
316
- end
317
-
318
- def cached_action_link_url_options(link, record)
319
- @action_links_url_options ||= {}
320
- @action_links_url_options[link.name_to_cache] || begin
321
- options = action_link_url_options(link, record)
322
- if cache_action_link_url_options?(link, record)
323
- @action_links_url_options[link.name_to_cache] = options
324
- end
325
- options
326
- end
327
- end
328
-
329
- def action_link_url_options(link, record)
330
- url_options = {:action => link.action}
331
- url_options[:id] = '--ID--' unless record.nil?
332
- url_options[:controller] = link.controller.to_s if link.controller
333
- url_options.merge! link.parameters if link.parameters
334
- if link.dynamic_parameters.is_a?(Proc)
335
- if record.nil?
336
- url_options.merge! instance_exec &link.dynamic_parameters
337
- else
338
- url_options.merge! instance_exec record, &link.dynamic_parameters
339
- end
340
- end
341
- if link.nested_link?
342
- url_options_for_nested_link(link.column, record, link, url_options)
343
- elsif nested?
344
- url_options[nested.param_name] = '--CHILD_ID--'
345
- end
346
- url_options_for_sti_link(link.column, record, link, url_options) unless record.nil? || active_scaffold_config.sti_children.nil?
347
- url_options[:_method] = link.method if !link.confirm? && link.inline? && link.method != :get
348
- url_options
349
- end
350
-
351
- def action_link_text(link, options)
352
- text = image_tag(link.image[:name], :size => link.image[:size], :alt => options[:link] || link.label, :title => options[:link] || link.label) if link.image
353
- text || options[:link]
354
- end
355
-
356
- def replaced_action_link_url_options(link, record)
357
- url = cached_action_link_url_options(link, record)
358
- url[:controller] ||= params[:controller]
359
- missing_options, url_options = url.partition { |_, v| v.nil? }
360
- replacements = {}
361
- replacements['--ID--'] = record.id.to_s if record
362
- if link.column.try(:singular_association?)
363
- replacements['--CHILD_ID--'] = record.send(link.column.association.name).try(:id).to_s
364
- elsif nested?
365
- replacements['--CHILD_ID--'] = params[nested.param_name].to_s
366
- end
367
- url_options.collect! do |k, v|
368
- [k.to_s, replacements[v] || v]
369
- end
370
- [missing_options, url_options]
371
- end
372
-
373
- def action_link_selected?(link, record)
374
- missing_options, url_options = replaced_action_link_url_options(link, record)
375
- (url_options - params.to_a).blank? && missing_options.all? { |k, _| params[k].nil? }
376
- end
377
-
378
- def action_link_html_options(link, record, options)
379
- link_id = get_action_link_id(link, record)
380
- html_options = link.html_options.merge(:class => [link.html_options[:class], link.action.to_s].compact.join(' '))
381
- html_options[:link] = action_link_text(link, options)
382
-
383
- # Needs to be in html_options to as the adding _method to the url is no longer supported by Rails
384
- html_options[:method] = link.method if link.method != :get
385
-
386
- html_options[:data] ||= {}
387
- html_options[:data][:confirm] = link.confirm(h(record.try(:to_label))) if link.confirm?
388
- if link.inline?
389
- html_options[:class] << ' as_action'
390
- html_options[:data][:position] = link.position if link.position
391
- html_options[:data][:action] = link.action
392
- html_options[:data][:cancel_refresh] = true if link.refresh_on_close
393
- html_options[:data][:keep_open] = true if link.keep_open?
394
- end
395
-
396
- if link.toggle
397
- html_options[:class] << ' toggle'
398
- html_options[:class] << ' active' if action_link_selected?(link, record)
399
- end
400
-
401
- html_options[:target] = '_blank' if link.popup?
402
- html_options[:id] = link_id
403
- html_options[:remote] = true unless link.page? || link.popup?
404
- if link.dhtml_confirm?
405
- unless link.inline?
406
- html_options[:class] << ' as_action'
407
- html_options[:page_link] = 'true'
408
- end
409
- html_options[:dhtml_confirm] = link.dhtml_confirm.value
410
- html_options[:onclick] = link.dhtml_confirm.onclick_function(controller, link_id)
411
- end
412
- html_options
413
- end
414
-
415
- def get_action_link_id(link, record = nil, column = nil)
416
- column ||= link.column
417
- if column && column.plural_association?
418
- id = "#{column.association.name}-#{record.id}"
419
- elsif column && column.singular_association?
420
- if record.try(column.association.name.to_sym).present?
421
- id = "#{column.association.name}-#{record.send(column.association.name).id}-#{record.id}"
422
- else
423
- id = "#{column.association.name}-#{record.id}" unless record.nil?
424
- end
425
- end
426
- id ||= record.try(:id) || (nested? ? nested_parent_id : '')
427
- action_id = "#{id_from_controller("#{link.controller}-") if params[:parent_controller] || (link.controller && link.controller != controller.controller_path)}#{link.action}"
428
- action_link_id(action_id, id)
429
- end
430
-
431
- def action_link_html(link, url, html_options, record)
432
- label = html_options.delete(:link)
433
- label ||= link.label
434
- if url.nil?
435
- content_tag(:a, label, html_options)
436
- else
437
- link_to(label, url, html_options)
438
- end
439
- end
440
-
441
- def url_options_for_nested_link(column, record, link, url_options)
442
- if column && column.association
443
- url_options[:parent_scaffold] = controller_path
444
- url_options[column.association.active_record.name.foreign_key.to_sym] = url_options.delete(:id)
445
- if column.singular_association? && url_options[:action].to_sym != :index
446
- url_options[:id] = '--CHILD_ID--'
447
- else
448
- url_options[:id] = nil
449
- end
450
- elsif link.parameters && link.parameters[:named_scope]
451
- url_options[:parent_scaffold] = controller_path
452
- url_options[active_scaffold_config.model.name.foreign_key.to_sym] = url_options.delete(:id)
453
- end
454
- end
455
-
456
- def url_options_for_sti_link(column, record, link, url_options)
457
- # need to find out controller of current record type and set parameters
458
- # it's quite difficult to detect an sti link
459
- # if link.column.nil? we are sure that it isn't a singular association inline autolink
460
- # however that will not work if a sti parent is a singular association inline autolink
461
- return unless link.column.nil?
462
- return if (sti_controller_path = controller_path_for_activerecord(record.class)).nil?
463
- url_options[:controller] = sti_controller_path
464
- url_options[:parent_sti] = controller_path
465
- end
466
-
467
78
  def list_row_class_method(record)
468
79
  return @_list_row_class_method if defined? @_list_row_class_method
469
80
  class_override_helper = "#{clean_class_name(record.class.name)}_list_row_class"
@@ -488,6 +99,7 @@ module ActiveScaffold
488
99
  classes << 'sorted ' if active_scaffold_config.actions.include?(:list) && active_scaffold_config.list.user.sorting.sorts_on?(column)
489
100
  classes << 'numeric ' if column.number?
490
101
  classes << column.css_class unless column.css_class.nil? || column.css_class.is_a?(Proc)
102
+ classes
491
103
  end
492
104
  classes = "#{@_column_classes[column.name]} "
493
105
  classes << 'empty ' if column_empty? column_value
@@ -514,6 +126,9 @@ module ActiveScaffold
514
126
 
515
127
  def column_empty?(column_value)
516
128
  empty = column_value.nil?
129
+ # column_value != false would force boolean to be cast to integer
130
+ # when comparing to column_value of IPAddr class (PostgreSQL inet column type)
131
+ # rubocop:disable Style/YodaCondition
517
132
  empty ||= false != column_value && column_value.blank?
518
133
  empty ||= ['&nbsp;', empty_field_text].include? column_value if column_value.is_a? String
519
134
  empty
@@ -523,35 +138,16 @@ module ActiveScaffold
523
138
  active_scaffold_config.list.empty_field_text if active_scaffold_config.actions.include?(:list)
524
139
  end
525
140
 
526
- def column_calculation(column)
527
- if column.calculate.instance_of? Proc
528
- column.calculate.call(@records)
529
- else
530
- calculate_query.calculate(column.calculate, column.name)
531
- end
532
- end
533
-
534
- def render_column_calculation(column)
535
- calculation = column_calculation(column)
536
- override_formatter = "render_#{column.name}_#{column.calculate.is_a?(Proc) ? :calculate : column.calculate}"
537
- calculation = send(override_formatter, calculation) if respond_to? override_formatter
538
- format_column_calculation(column, calculation)
539
- end
540
-
541
- def format_column_calculation(column, calculation)
542
- "#{"#{as_(column.calculate)}: " unless column.calculate.is_a? Proc}#{format_column_value nil, column, calculation}"
543
- end
544
-
545
141
  def as_slider(options)
546
142
  content_tag(:span, '', class: 'as-slider', data: {slider: options})
547
143
  end
548
144
 
549
145
  def clean_column_name(name)
550
- name.to_s.gsub('?', '')
146
+ name.to_s.delete('?')
551
147
  end
552
148
 
553
149
  def clean_class_name(name)
554
- name.underscore.gsub('/', '_')
150
+ name.underscore.tr('/', '_')
555
151
  end
556
152
 
557
153
  # the naming convention for overriding with helpers
@@ -575,7 +171,24 @@ module ActiveScaffold
575
171
  end
576
172
  end
577
173
 
174
+ def history_state
175
+ if active_scaffold_config.store_user_settings
176
+ state = {page: @page.try(:number)}
177
+ state[:search] = search_params if respond_to?(:search_params) && search_params.present?
178
+ if active_scaffold_config.list.user.user_sorting?
179
+ column, state[:sort_direction] = active_scaffold_config.list.user.sorting.first
180
+ state[:sort] = column.name
181
+ else
182
+ state.merge sort: '', sort_direction: ''
183
+ end
184
+ state
185
+ else
186
+ {}
187
+ end
188
+ end
189
+
578
190
  def display_message(message)
191
+ message = safe_join message, tag(:br) if message.is_a?(Array)
579
192
  if (highlights = active_scaffold_config.highlight_messages)
580
193
  message = highlights.inject(message) do |msg, (phrases, highlighter)|
581
194
  highlight(msg, phrases, highlighter || {})
@@ -583,7 +196,9 @@ module ActiveScaffold
583
196
  end
584
197
  if (format = active_scaffold_config.timestamped_messages)
585
198
  format = :short if format == true
586
- message = "#{content_tag :div, l(Time.current, :format => format), :class => 'timestamp'} #{content_tag :div, message, :class => 'message-content'}".html_safe
199
+ messages = [content_tag(:div, l(Time.current, :format => format), :class => 'timestamp')]
200
+ messages << content_tag(:div, message, :class => 'message-content')
201
+ message = safe_join messages, ' '
587
202
  end
588
203
  message
589
204
  end
@@ -610,10 +225,10 @@ module ActiveScaffold
610
225
  ''
611
226
  else
612
227
  html = {}
613
- [:id, :class].each do |key|
228
+ %i[id class].each do |key|
614
229
  if options.include?(key)
615
230
  value = options[key]
616
- html[key] = value unless value.blank?
231
+ html[key] = value if value.present?
617
232
  else
618
233
  html[key] = 'errorExplanation'
619
234
  end
@@ -624,7 +239,7 @@ module ActiveScaffold
624
239
  if options.include?(:header_message)
625
240
  options[:header_message]
626
241
  else
627
- as_('errors.template.header', :count => count, :model => options[:object_name].to_s.gsub('_', ' '))
242
+ as_('errors.template.header', :count => count, :model => options[:object_name].to_s.tr('_', ' '))
628
243
  end
629
244
 
630
245
  message = options.include?(:message) ? options[:message] : as_('errors.template.body')
@@ -636,16 +251,16 @@ module ActiveScaffold
636
251
  end
637
252
  error_messages =
638
253
  if options[:list_type] == :br
639
- error_messages.join('<br/>').html_safe
254
+ safe_join error_messages, tag(:br)
640
255
  else
641
- content_tag(options[:list_type], error_messages.join.html_safe)
256
+ content_tag options[:list_type], safe_join(error_messages)
642
257
  end
643
258
 
644
259
  contents = []
645
- contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank?
646
- contents << content_tag(:p, message) unless message.blank?
260
+ contents << content_tag(options[:header_tag] || :h2, header_message) if header_message.present?
261
+ contents << content_tag(:p, message) if message.present?
647
262
  contents << error_messages
648
- contents = contents.join.html_safe
263
+ contents = safe_join(contents)
649
264
  options[:container_tag] ? content_tag(options[:container_tag], contents, html) : contents
650
265
  end
651
266
  end