active_scaffold 3.5.4 → 3.6.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 (192) hide show
  1. checksums.yaml +4 -4
  2. data/{CHANGELOG → CHANGELOG.rdoc} +72 -0
  3. data/README.md +20 -8
  4. data/app/assets/javascripts/active_scaffold.js.erb +0 -1
  5. data/app/assets/javascripts/jquery/active_scaffold.js +98 -7
  6. data/app/assets/stylesheets/active_scaffold_colors.scss +1 -1
  7. data/app/assets/stylesheets/active_scaffold_layout.css +52 -29
  8. data/app/views/active_scaffold_overrides/_base_form.html.erb +2 -2
  9. data/app/views/active_scaffold_overrides/_form.html.erb +1 -1
  10. data/app/views/active_scaffold_overrides/_form_association.html.erb +2 -1
  11. data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +3 -2
  12. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +9 -7
  13. data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +4 -4
  14. data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +2 -1
  15. data/app/views/active_scaffold_overrides/_list.html.erb +2 -1
  16. data/app/views/active_scaffold_overrides/_list_header.html.erb +5 -7
  17. data/app/views/active_scaffold_overrides/_list_messages.html.erb +1 -0
  18. data/app/views/active_scaffold_overrides/_list_record.html.erb +4 -5
  19. data/app/views/active_scaffold_overrides/_list_with_header.html.erb +1 -1
  20. data/app/views/active_scaffold_overrides/_messages.html.erb +1 -0
  21. data/app/views/active_scaffold_overrides/_refresh_list.js.erb +4 -0
  22. data/app/views/active_scaffold_overrides/_render_field.js.erb +2 -1
  23. data/app/views/active_scaffold_overrides/_show_association_horizontal.html.erb +2 -1
  24. data/app/views/active_scaffold_overrides/_show_columns.html.erb +2 -2
  25. data/app/views/active_scaffold_overrides/_show_horizontal_record.html.erb +4 -4
  26. data/app/views/active_scaffold_overrides/_update_calculations.js.erb +1 -1
  27. data/app/views/active_scaffold_overrides/_update_column.js.erb +2 -2
  28. data/app/views/active_scaffold_overrides/_vertical_subform.html.erb +2 -2
  29. data/app/views/active_scaffold_overrides/action_confirmation.html.erb +2 -2
  30. data/app/views/active_scaffold_overrides/delete.html.erb +2 -2
  31. data/app/views/active_scaffold_overrides/on_action_update.js.erb +16 -6
  32. data/app/views/active_scaffold_overrides/on_update.js.erb +1 -1
  33. data/app/views/active_scaffold_overrides/row.js.erb +1 -1
  34. data/app/views/active_scaffold_overrides/update_column.js.erb +2 -2
  35. data/config/locales/de.yml +2 -1
  36. data/config/locales/en.yml +1 -0
  37. data/config/locales/es.yml +1 -0
  38. data/config/locales/fr.yml +2 -1
  39. data/config/locales/hu.yml +1 -0
  40. data/config/locales/ja.yml +1 -0
  41. data/config/locales/ru.yml +1 -0
  42. data/lib/active_scaffold.rb +19 -16
  43. data/lib/active_scaffold/actions/common_search.rb +11 -8
  44. data/lib/active_scaffold/actions/core.rb +91 -70
  45. data/lib/active_scaffold/actions/create.rb +28 -28
  46. data/lib/active_scaffold/actions/delete.rb +3 -3
  47. data/lib/active_scaffold/actions/field_search.rb +53 -43
  48. data/lib/active_scaffold/actions/list.rb +111 -27
  49. data/lib/active_scaffold/actions/nested.rb +65 -48
  50. data/lib/active_scaffold/actions/search.rb +1 -1
  51. data/lib/active_scaffold/actions/show.rb +4 -4
  52. data/lib/active_scaffold/actions/subform.rb +23 -22
  53. data/lib/active_scaffold/actions/update.rb +96 -77
  54. data/lib/active_scaffold/active_record_permissions.rb +2 -11
  55. data/lib/active_scaffold/attribute_params.rb +102 -94
  56. data/lib/active_scaffold/bridges.rb +8 -8
  57. data/lib/active_scaffold/bridges/active_storage.rb +6 -0
  58. data/lib/active_scaffold/bridges/active_storage/active_storage_bridge.rb +34 -0
  59. data/lib/active_scaffold/bridges/active_storage/active_storage_helpers.rb +54 -0
  60. data/lib/active_scaffold/bridges/active_storage/form_ui.rb +22 -0
  61. data/lib/active_scaffold/bridges/active_storage/list_ui.rb +36 -0
  62. data/lib/active_scaffold/bridges/bitfields.rb +2 -1
  63. data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +12 -15
  64. data/lib/active_scaffold/bridges/bitfields/list_ui.rb +19 -0
  65. data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +1 -1
  66. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +9 -12
  67. data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +1 -1
  68. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +2 -2
  69. data/lib/active_scaffold/bridges/chosen/helpers.rb +7 -6
  70. data/lib/active_scaffold/bridges/date_picker/ext.rb +0 -13
  71. data/lib/active_scaffold/bridges/date_picker/helper.rb +49 -44
  72. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +1 -1
  73. data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +1 -1
  74. data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +3 -3
  75. data/lib/active_scaffold/bridges/file_column/form_ui.rb +3 -3
  76. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +10 -7
  77. data/lib/active_scaffold/bridges/paper_trail.rb +1 -1
  78. data/lib/active_scaffold/bridges/paper_trail/actions.rb +3 -1
  79. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
  80. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +1 -1
  81. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +2 -2
  82. data/lib/active_scaffold/bridges/record_select/helpers.rb +15 -17
  83. data/lib/active_scaffold/bridges/shared/date_bridge.rb +20 -19
  84. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +3 -1
  85. data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +21 -4
  86. data/lib/active_scaffold/config/base.rb +133 -41
  87. data/lib/active_scaffold/config/core.rb +146 -18
  88. data/lib/active_scaffold/config/delete.rb +14 -1
  89. data/lib/active_scaffold/config/field_search.rb +7 -1
  90. data/lib/active_scaffold/config/form.rb +10 -1
  91. data/lib/active_scaffold/config/list.rb +39 -13
  92. data/lib/active_scaffold/config/mark.rb +4 -2
  93. data/lib/active_scaffold/config/nested.rb +16 -17
  94. data/lib/active_scaffold/config/search.rb +9 -0
  95. data/lib/active_scaffold/config/show.rb +4 -0
  96. data/lib/active_scaffold/config/update.rb +4 -0
  97. data/lib/active_scaffold/configurable.rb +14 -7
  98. data/lib/active_scaffold/constraints.rb +22 -20
  99. data/lib/active_scaffold/core.rb +67 -28
  100. data/lib/active_scaffold/data_structures/action_columns.rb +50 -59
  101. data/lib/active_scaffold/data_structures/action_link.rb +50 -20
  102. data/lib/active_scaffold/data_structures/action_links.rb +15 -13
  103. data/lib/active_scaffold/data_structures/association/abstract.rb +38 -15
  104. data/lib/active_scaffold/data_structures/association/active_mongoid.rb +2 -6
  105. data/lib/active_scaffold/data_structures/association/active_record.rb +6 -2
  106. data/lib/active_scaffold/data_structures/association/mongoid.rb +0 -3
  107. data/lib/active_scaffold/data_structures/column.rb +75 -66
  108. data/lib/active_scaffold/data_structures/columns.rb +3 -2
  109. data/lib/active_scaffold/data_structures/nested_info.rb +33 -19
  110. data/lib/active_scaffold/data_structures/set.rb +8 -0
  111. data/lib/active_scaffold/data_structures/sorting.rb +10 -2
  112. data/lib/active_scaffold/delayed_setup.rb +16 -5
  113. data/lib/active_scaffold/extensions/action_controller_rendering.rb +3 -2
  114. data/lib/active_scaffold/extensions/action_view_rendering.rb +93 -32
  115. data/lib/active_scaffold/extensions/cow_proxy.rb +95 -0
  116. data/lib/active_scaffold/extensions/ice_nine.rb +36 -0
  117. data/lib/active_scaffold/extensions/left_outer_joins.rb +8 -33
  118. data/lib/active_scaffold/extensions/localize.rb +3 -1
  119. data/lib/active_scaffold/extensions/routing_mapper.rb +6 -45
  120. data/lib/active_scaffold/extensions/to_label.rb +3 -2
  121. data/lib/active_scaffold/extensions/unsaved_record.rb +2 -4
  122. data/lib/active_scaffold/finder.rb +110 -77
  123. data/lib/active_scaffold/helpers/action_link_helpers.rb +62 -36
  124. data/lib/active_scaffold/helpers/association_helpers.rb +18 -16
  125. data/lib/active_scaffold/helpers/controller_helpers.rb +34 -10
  126. data/lib/active_scaffold/helpers/form_column_helpers.rb +196 -124
  127. data/lib/active_scaffold/helpers/human_condition_helpers.rb +1 -1
  128. data/lib/active_scaffold/helpers/id_helpers.rb +6 -2
  129. data/lib/active_scaffold/helpers/list_column_helpers.rb +90 -57
  130. data/lib/active_scaffold/helpers/pagination_helpers.rb +2 -2
  131. data/lib/active_scaffold/helpers/search_column_helpers.rb +29 -34
  132. data/lib/active_scaffold/helpers/show_column_helpers.rb +3 -5
  133. data/lib/active_scaffold/helpers/view_helpers.rb +39 -36
  134. data/lib/active_scaffold/marked_model.rb +2 -2
  135. data/lib/active_scaffold/orm_checks.rb +3 -7
  136. data/lib/active_scaffold/paginator.rb +7 -7
  137. data/lib/active_scaffold/registry.rb +33 -0
  138. data/lib/active_scaffold/responds_to_parent.rb +8 -11
  139. data/lib/active_scaffold/tableless.rb +82 -66
  140. data/lib/active_scaffold/version.rb +2 -2
  141. data/lib/generators/active_scaffold/controller_generator.rb +2 -2
  142. data/lib/generators/active_scaffold/install_generator.rb +52 -4
  143. data/lib/generators/active_scaffold/resource_generator.rb +2 -2
  144. data/shoulda_macros/macros.rb +3 -1
  145. data/test/bridges/date_picker_test.rb +1 -2
  146. data/test/bridges/paperclip_test.rb +6 -6
  147. data/test/class_with_finder.rb +2 -2
  148. data/test/company.rb +4 -4
  149. data/test/config/create_test.rb +4 -2
  150. data/test/config/nested_test.rb +1 -1
  151. data/test/config/show_test.rb +1 -1
  152. data/test/config/update_test.rb +7 -6
  153. data/test/data_structures/action_columns_test.rb +2 -2
  154. data/test/data_structures/action_links_test.rb +1 -1
  155. data/test/data_structures/column_test.rb +3 -6
  156. data/test/data_structures/columns_test.rb +2 -2
  157. data/test/data_structures/sorting_test.rb +7 -0
  158. data/test/extensions/action_view_rendering_test.rb +20 -0
  159. data/test/extensions/active_record_test.rb +4 -4
  160. data/test/extensions/routing_mapper_test.rb +2 -2
  161. data/test/helpers/list_column_helpers_test.rb +3 -1
  162. data/test/misc/active_record_permissions_test.rb +3 -11
  163. data/test/misc/attribute_params_test.rb +12 -8
  164. data/test/misc/calculation_test.rb +1 -1
  165. data/test/misc/configurable_test.rb +10 -10
  166. data/test/misc/constraints_test.rb +2 -2
  167. data/test/misc/convert_numbers_format_test.rb +7 -3
  168. data/test/misc/lang_test.rb +1 -1
  169. data/test/misc/parse_datetime_test.rb +3 -4
  170. data/test/misc/tableless_test.rb +14 -0
  171. data/test/mock_app/Rakefile +1 -1
  172. data/test/mock_app/app/assets/config/manifest.js +0 -0
  173. data/test/mock_app/app/controllers/cars_controller.rb +1 -0
  174. data/test/mock_app/app/controllers/people_controller.rb +5 -1
  175. data/test/mock_app/app/controllers/roles_controller.rb +4 -0
  176. data/test/mock_app/app/views/active_scaffold_overrides/_form.html.erb +2 -0
  177. data/test/mock_app/app/views/active_scaffold_overrides/list.html.erb +2 -0
  178. data/test/mock_app/app/views/people/_first_name_form_column.html.erb +2 -0
  179. data/test/mock_app/app/views/people/_form.html.erb +2 -0
  180. data/test/mock_app/app/views/people/list.html.erb +2 -0
  181. data/test/mock_app/config/application.rb +2 -1
  182. data/test/mock_app/config/boot.rb +1 -1
  183. data/test/mock_app/config/environment.rb +2 -2
  184. data/test/mock_app/config/routes.rb +4 -1
  185. data/test/mock_app/db/schema.rb +2 -0
  186. data/test/performance/list_cars_performance_test.rb +34 -0
  187. data/test/performance/list_people_performance_test.rb +31 -0
  188. data/test/performance_test_help.rb +3 -0
  189. data/test/test_helper.rb +12 -4
  190. metadata +69 -18
  191. data/app/assets/javascripts/prototype/rico_corner.js +0 -370
  192. data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +0 -7
@@ -14,12 +14,10 @@ module ActiveScaffold
14
14
  # second, check if the dev has specified a valid list_ui for this column
15
15
  elsif column.show_ui && (method = override_show_column_ui(column.show_ui))
16
16
  send(method, value_record, column)
17
+ elsif column.column && (method = override_show_column_ui(column.column.type))
18
+ send(method, value_record, column)
17
19
  else
18
- if column.column && (method = override_show_column_ui(column.column.type))
19
- send(method, value_record, column)
20
- else
21
- get_column_value(record, column)
22
- end
20
+ get_column_value(record, column)
23
21
  end
24
22
  end
25
23
 
@@ -17,17 +17,10 @@ module ActiveScaffold
17
17
  ## Delegates
18
18
  ##
19
19
 
20
- # access to the configuration variable
21
- def active_scaffold_config
22
- controller.class.active_scaffold_config
23
- end
24
-
25
- def active_scaffold_config_for(*args)
26
- controller.class.active_scaffold_config_for(*args)
27
- end
28
-
29
- def active_scaffold_controller_for(*args)
30
- controller.class.active_scaffold_controller_for(*args)
20
+ def active_scaffold_controller_for(klass)
21
+ ActiveScaffold::Registry.cache :as_controller, klass do
22
+ controller.class.active_scaffold_controller_for(klass)
23
+ end
31
24
  end
32
25
 
33
26
  ##
@@ -44,8 +37,11 @@ module ActiveScaffold
44
37
  # This is the template finder logic, keep it updated with however we find stuff in rails
45
38
  # currently this very similar to the logic in ActionBase::Base.render for options file
46
39
  def template_exists?(template_name, partial = false)
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
40
+ if @_view_paths
41
+ restore_view_paths = lookup_context.view_paths
42
+ lookup_context.view_paths = @_view_paths
43
+ end
44
+ (@_lookup_context || lookup_context).exists?(template_name, '', partial).tap do
49
45
  lookup_context.view_paths = restore_view_paths if @_view_paths
50
46
  end
51
47
  end
@@ -62,17 +58,22 @@ module ActiveScaffold
62
58
 
63
59
  # a general-use loading indicator (the "stuff is happening, please wait" feedback)
64
60
  def loading_indicator_tag(options)
65
- image_tag 'active_scaffold/indicator.gif', :style => 'visibility:hidden;', :id => loading_indicator_id(options), :alt => 'loading indicator', :class => 'loading-indicator'
61
+ # it's call many times and we can cache same result
62
+ @_loading_indicator_path ||= image_path('active_scaffold/indicator.gif')
63
+ # it's call many times in long lists, image_tag is a bit slower
64
+ tag :img, src: @_loading_indicator_path, style: 'visibility:hidden;', id: loading_indicator_id(options), alt: 'loading indicator', class: 'loading-indicator'
66
65
  end
67
66
 
68
67
  # Creates a javascript-based link that toggles the visibility of some element on the page.
69
- # By default, it toggles the visibility of the sibling after the one it's nested in. You may pass custom javascript logic in options[:of] to change that, though. For example, you could say :of => '$("my_div_id")'.
68
+ # By default, it toggles the visibility of the sibling after the one it's nested in.
69
+ # You may pass custom javascript logic in options[:of] to change that, though. For example, you could say :of => '$("my_div_id")'.
70
70
  # You may also flag whether the other element is visible by default or not, and the initial text will adjust accordingly.
71
71
  def link_to_visibility_toggle(id, options = {})
72
- options[:default_visible] = true if options[:default_visible].nil?
73
72
  options[:hide_label] ||= as_(:hide)
74
73
  options[:show_label] ||= as_(:show_block)
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'
74
+ label = options[:default_visible].nil? || options[:default_visible] ? options[:hide_label] : options[:show_label]
75
+ data = {:show => options[:show_label], :hide => options[:hide_label], :toggable => id}
76
+ link_to label, '#', :data => data, :style => 'display: none;', :class => 'as-js-button visibility-toggle'
76
77
  end
77
78
 
78
79
  def list_row_class_method(record)
@@ -86,6 +87,10 @@ module ActiveScaffold
86
87
  class_override_helper ? send(class_override_helper, record) : ''
87
88
  end
88
89
 
90
+ def list_row_attributes(tr_class, tr_id, data_refresh)
91
+ {class: "record #{tr_class}", id: tr_id, data: {refresh: data_refresh}}
92
+ end
93
+
89
94
  def column_attributes(column, record)
90
95
  method = override_helper column, 'column_attributes'
91
96
  return send(method, record) if method
@@ -93,15 +98,14 @@ module ActiveScaffold
93
98
  end
94
99
 
95
100
  def column_class(column, column_value, record)
96
- @_column_classes ||= {}
97
- @_column_classes[column.name] ||= begin
101
+ classes = ActiveScaffold::Registry.cache :column_classes, column.cache_key do
98
102
  classes = "#{column.name}-column "
99
103
  classes << 'sorted ' if active_scaffold_config.actions.include?(:list) && active_scaffold_config.list.user.sorting.sorts_on?(column)
100
104
  classes << 'numeric ' if column.number?
101
- classes << column.css_class unless column.css_class.nil? || column.css_class.is_a?(Proc)
105
+ classes << column.css_class << ' ' unless column.css_class.nil? || column.css_class.is_a?(Proc)
102
106
  classes
103
107
  end
104
- classes = "#{@_column_classes[column.name]} "
108
+ classes = classes.dup
105
109
  classes << 'empty ' if column_empty? column_value
106
110
  classes << 'in_place_editor_field ' if inplace_edit?(record, column) || column.list_ui == :marked
107
111
  if column.css_class.is_a?(Proc)
@@ -124,18 +128,23 @@ module ActiveScaffold
124
128
  classes
125
129
  end
126
130
 
131
+ def as_main_div_data
132
+ params[:eid] ? {eid: id_from_controller(params[:eid])} : {}
133
+ end
134
+
127
135
  def column_empty?(column_value)
136
+ @_empty_values ||= ['&nbsp;', empty_field_text].compact
128
137
  empty = column_value.nil?
129
138
  # column_value != false would force boolean to be cast to integer
130
139
  # when comparing to column_value of IPAddr class (PostgreSQL inet column type)
131
- # rubocop:disable Style/YodaCondition
132
- empty ||= false != column_value && column_value.blank?
133
- empty ||= ['&nbsp;', empty_field_text].include? column_value if column_value.is_a? String
140
+ empty ||= false != column_value && column_value.blank? # rubocop:disable Style/YodaCondition
141
+ empty ||= @_empty_values.include? column_value
134
142
  empty
135
143
  end
136
144
 
137
145
  def empty_field_text
138
- active_scaffold_config.list.empty_field_text if active_scaffold_config.actions.include?(:list)
146
+ return @_empty_field_text if defined? @_empty_field_text
147
+ @_empty_field_text = (active_scaffold_config.list.empty_field_text if active_scaffold_config.actions.include?(:list))
139
148
  end
140
149
 
141
150
  def as_slider(options)
@@ -156,11 +165,7 @@ module ActiveScaffold
156
165
  end
157
166
 
158
167
  def override_helper(column, suffix)
159
- hash = @_override_helpers ||= {}
160
- hash = hash[suffix] ||= {}
161
- hash = hash[column.active_record_class.name] ||= {}
162
- return hash[column.name] if hash.include? column.name
163
- hash[column.name] = begin
168
+ ActiveScaffold::Registry.cache suffix, column.cache_key do
164
169
  method_with_class = override_helper_name(column, suffix, true)
165
170
  if respond_to?(method_with_class)
166
171
  method_with_class
@@ -173,7 +178,7 @@ module ActiveScaffold
173
178
 
174
179
  def history_state
175
180
  if active_scaffold_config.store_user_settings
176
- state = {page: @page.try(:number)}
181
+ state = {page: @page&.number}
177
182
  state[:search] = search_params if respond_to?(:search_params) && search_params.present?
178
183
  if active_scaffold_config.list.user.user_sorting?
179
184
  column, state[:sort_direction] = active_scaffold_config.list.user.sorting.first
@@ -189,12 +194,12 @@ module ActiveScaffold
189
194
 
190
195
  def display_message(message)
191
196
  message = safe_join message, tag(:br) if message.is_a?(Array)
192
- if (highlights = active_scaffold_config.highlight_messages)
197
+ if (highlights = active_scaffold_config.user.highlight_messages)
193
198
  message = highlights.inject(message) do |msg, (phrases, highlighter)|
194
199
  highlight(msg, phrases, highlighter || {})
195
200
  end
196
201
  end
197
- if (format = active_scaffold_config.timestamped_messages)
202
+ if (format = active_scaffold_config.user.timestamped_messages)
198
203
  format = :short if format == true
199
204
  messages = [content_tag(:div, l(Time.current, :format => format), :class => 'timestamp')]
200
205
  messages << content_tag(:div, message, :class => 'message-content')
@@ -211,9 +216,7 @@ module ActiveScaffold
211
216
  object = instance_variable_get("@#{object}") unless object.respond_to?(:to_model)
212
217
  object = convert_to_model(object)
213
218
 
214
- if object.class.respond_to?(:model_name)
215
- options[:object_name] ||= object.class.model_name.human.downcase
216
- end
219
+ options[:object_name] ||= object.class.model_name.human.downcase if object.class.respond_to?(:model_name)
217
220
 
218
221
  object
219
222
  end
@@ -24,11 +24,11 @@ module ActiveScaffold
24
24
 
25
25
  module ClassMethods
26
26
  def marked_records
27
- Thread.current[:marked_records] ||= {}
27
+ ActiveScaffold::Registry.marked_records ||= {}
28
28
  end
29
29
 
30
30
  def marked_records=(marked)
31
- Thread.current[:marked_records] = marked
31
+ ActiveScaffold::Registry.marked_records = marked
32
32
  end
33
33
 
34
34
  def marked_record_ids
@@ -43,7 +43,7 @@ module ActiveScaffold
43
43
  elsif mongoid? klass
44
44
  klass.fields
45
45
  else
46
- []
46
+ {}
47
47
  end
48
48
  end
49
49
 
@@ -69,13 +69,9 @@ module ActiveScaffold
69
69
 
70
70
  def type_for_attribute(klass, column_name)
71
71
  if active_record? klass
72
- if klass.respond_to? :type_for_attribute
73
- klass.type_for_attribute column_name.to_s
74
- else # Rails.version < 4.2
75
- klass.column_types[column_name.to_s]
76
- end
72
+ klass.type_for_attribute column_name.to_s
77
73
  elsif mongoid? klass
78
- klass.fields[column_name.to_s].type
74
+ klass.fields[column_name.to_s]&.type
79
75
  end
80
76
  end
81
77
 
@@ -19,16 +19,15 @@ class Paginator
19
19
  # (and the number of items to show per page, for
20
20
  # convenience, if the arity is 2)
21
21
  def initialize(count, per_page, &select)
22
- @count, @per_page = count, per_page
23
- unless select
24
- raise MissingSelectError, 'Must provide block to select data for each page'
25
- end
22
+ @count = count
23
+ @per_page = per_page
24
+ raise MissingSelectError, 'Must provide block to select data for each page' unless select
26
25
  @select = select
27
26
  end
28
27
 
29
28
  # Total number of pages
30
29
  def number_of_pages
31
- (@count / @per_page).to_i + (@count % @per_page > 0 ? 1 : 0)
30
+ (@count / @per_page).to_i + ((@count % @per_page).positive? ? 1 : 0)
32
31
  end
33
32
 
34
33
  # First page object
@@ -57,7 +56,7 @@ class Paginator
57
56
 
58
57
  # Retrieve page object by number
59
58
  def page(number)
60
- number = (n = number.to_i) > 0 ? n : 1
59
+ number = [1, number.to_i].max
61
60
  Page.new(self, number) do
62
61
  offset = (number - 1) * @per_page
63
62
  args = [offset]
@@ -80,7 +79,8 @@ class Paginator
80
79
  attr_reader :number, :pager
81
80
 
82
81
  def initialize(pager, number, &select) #:nodoc:
83
- @pager, @number = pager, number
82
+ @pager = pager
83
+ @number = number
84
84
  @offset = (number - 1) * pager.per_page
85
85
  @select = select
86
86
  end
@@ -0,0 +1,33 @@
1
+ module ActiveScaffold
2
+ class Registry
3
+ extend ActiveSupport::PerThreadRegistry
4
+ attr_accessor :current_user_proc, :current_ability_proc, :marked_records
5
+
6
+ def user_settings
7
+ @user_settings ||= {}
8
+ end
9
+
10
+ def constraint_columns
11
+ @constraint_columns ||= Hash.new { |h, k| h[k] = [] }
12
+ end
13
+
14
+ def unauthorized_columns
15
+ @unauthorized_columns ||= Hash.new { |h, k| h[k] = [] }
16
+ end
17
+
18
+ def cache(kind, key = nil, &block)
19
+ unless key
20
+ key = kind
21
+ kind = :cache
22
+ end
23
+ @cache ||= {}
24
+ cache = @cache[kind] ||= {}
25
+ return cache[key] if cache.include? key
26
+ cache[key] ||= yield
27
+ end
28
+
29
+ def self.instance
30
+ RequestStore.store[@per_thread_registry_key] ||= new
31
+ end
32
+ end
33
+ end
@@ -9,11 +9,12 @@ module ActiveScaffold
9
9
  return unless performed?
10
10
 
11
11
  # Either pull out a redirect or the request body
12
- script = if response.headers['Location']
13
- "document.location.href = '#{self.class.helpers.escape_javascript response.headers.delete('Location').to_s}'"
14
- else
15
- response.body || ''
16
- end
12
+ script =
13
+ if response.headers['Location']
14
+ "document.location.href = '#{self.class.helpers.escape_javascript response.headers.delete('Location').to_s}'"
15
+ else
16
+ response.body || ''
17
+ end
17
18
  response.status = 200 if (300...400).cover? response.status
18
19
 
19
20
  # Eval in parent scope and replace document location of this frame
@@ -34,12 +35,8 @@ module ActiveScaffold
34
35
  instance_variable_set(:@_response_body, nil)
35
36
  end
36
37
 
37
- # We're returning HTML instead of JS now
38
- if Rails.version < '4.1'
39
- render text: script, content_type: 'text/html' # remove when rails 4.0 is not supported
40
- else
41
- render html: script.html_safe, content_type: 'text/html' # rubocop:disable Rails/OutputSafety
42
- end
38
+ # We're returning HTML instead of JS now, content_type needed if not inside respond_to block
39
+ render html: script.html_safe, content_type: 'text/html' # rubocop:disable Rails/OutputSafety
43
40
  end
44
41
  alias respond_to_parent responds_to_parent
45
42
  end
@@ -1,10 +1,8 @@
1
- class ActiveScaffold::Tableless < ActiveRecord::Base
1
+ class ActiveScaffold::Tableless < ActiveRecord::Base # rubocop:disable Rails/ApplicationRecord
2
2
  class AssociationScope < ActiveRecord::Associations::AssociationScope
3
- if defined?(ActiveRecord::Associations::AssociationScope::INSTANCE) # rails >= 4.1
4
- INSTANCE = respond_to?(:create) ? create : new # create for rails >= 4.2
5
- def self.scope(association, connection)
6
- INSTANCE.scope association, connection
7
- end
3
+ INSTANCE = create
4
+ def self.scope(association, connection)
5
+ INSTANCE.scope association, connection
8
6
  end
9
7
 
10
8
  if Rails.version < '5.0.0'
@@ -19,11 +17,9 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
19
17
  end
20
18
  end
21
19
 
22
- if Rails.version >= '4.1'
23
- def add_constraints(scope, owner, assoc_klass, refl, tracker)
24
- tracker.instance_variable_set(:@assoc_klass, assoc_klass)
25
- super
26
- end
20
+ def add_constraints(scope, owner, assoc_klass, refl, tracker)
21
+ tracker.instance_variable_set(:@assoc_klass, assoc_klass)
22
+ super
27
23
  end
28
24
  end
29
25
  end
@@ -38,6 +34,12 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
38
34
  def columns(table_name)
39
35
  klass.columns
40
36
  end
37
+
38
+ if Rails.version >= '6.0.0'
39
+ def data_sources
40
+ klass ? [klass.table_name] : []
41
+ end
42
+ end
41
43
  end
42
44
 
43
45
  class Column < ActiveRecord::ConnectionAdapters::Column
@@ -46,7 +48,7 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
46
48
  metadata = ActiveRecord::Base.connection.send :fetch_type_metadata, sql_type
47
49
  super(name, default, metadata, null)
48
50
  end
49
- elsif Rails.version >= '4.2.0'
51
+ else
50
52
  def initialize(name, default, sql_type = nil, null = true)
51
53
  cast_type = ActiveRecord::Base.connection.send :lookup_cast_type, sql_type
52
54
  super(name, default, cast_type, sql_type, null)
@@ -55,16 +57,18 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
55
57
  end
56
58
 
57
59
  module Tableless
58
- def association_scope
59
- @association_scope ||= overrided_association_scope if klass < ActiveScaffold::Tableless
60
- super
61
- end
60
+ if Rails.version < '5.2.0'
61
+ def skip_statement_cache?
62
+ klass < ActiveScaffold::Tableless ? true : super
63
+ end
62
64
 
63
- def overrided_association_scope
64
- if AssociationScope.respond_to?(:scope) # rails >= 4.1
65
- AssociationScope.scope(self, klass.connection)
66
- else # rails < 4.1
67
- AssociationScope.new(self).scope
65
+ def association_scope
66
+ @association_scope ||= AssociationScope.scope(self, klass.connection) if klass < ActiveScaffold::Tableless
67
+ super
68
+ end
69
+ else
70
+ def skip_statement_cache?(scope)
71
+ klass < ActiveScaffold::Tableless ? true : super
68
72
  end
69
73
  end
70
74
 
@@ -84,19 +88,19 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
84
88
  end
85
89
 
86
90
  module TablelessCollectionAssociation
87
- def get_records
91
+ def get_records # rubocop:disable Naming/AccessorMethodName
88
92
  klass < ActiveScaffold::Tableless ? scope.to_a : super
89
93
  end
90
94
  end
91
95
 
92
96
  module CollectionAssociation
93
97
  def self.included(base)
94
- base.prepend TablelessCollectionAssociation if Rails.version >= '4.2'
98
+ base.prepend TablelessCollectionAssociation
95
99
  end
96
100
  end
97
101
 
98
102
  module TablelessSingularAssociation
99
- def get_records
103
+ def get_records # rubocop:disable Naming/AccessorMethodName
100
104
  klass < ActiveScaffold::Tableless ? scope.limit(1).to_a : super
101
105
  end
102
106
  end
@@ -110,20 +114,13 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
110
114
  module RelationExtension
111
115
  attr_reader :conditions
112
116
 
113
- if Rails.version >= '5.0'
114
- def initialize(klass, table, predicate_builder, values = {})
115
- super
116
- @conditions ||= []
117
- end
118
- else
119
- def initialize(klass, table)
120
- super
121
- @conditions ||= []
122
- end
117
+ def initialize(klass, *)
118
+ super
119
+ @conditions ||= []
123
120
  end
124
121
 
125
122
  def initialize_copy(other)
126
- @conditions = @conditions.try(:dup) || []
123
+ @conditions = @conditions&.dup || []
127
124
  super
128
125
  end
129
126
 
@@ -135,9 +132,9 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
135
132
  self
136
133
  end
137
134
 
138
- def merge(r)
135
+ def merge(rel)
139
136
  super.tap do |merged|
140
- merged.conditions.concat r.conditions unless r.nil? || r.is_a?(Array)
137
+ merged.conditions.concat rel.conditions unless rel.nil? || rel.is_a?(Array)
141
138
  end
142
139
  end
143
140
 
@@ -158,50 +155,72 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
158
155
  def execute_simple_calculation(operation, column_name, distinct)
159
156
  @klass.execute_simple_calculation(self, operation, column_name, distinct)
160
157
  end
158
+
159
+ def implicit_order_column
160
+ @klass.implicit_order_column
161
+ end
162
+
163
+ def exists?
164
+ limit(1).to_a.present?
165
+ end
161
166
  end
162
167
 
163
- class Relation < ActiveRecord::Relation
168
+ class Relation < ::ActiveRecord::Relation
164
169
  include RelationExtension
165
170
  end
166
171
  class << self
167
172
  private
168
173
 
169
174
  def relation
170
- args = [self, arel_table]
171
- args << predicate_builder if Rails.version >= '5.0.0'
175
+ args = [self]
176
+ if Rails.version < '5.2.0'
177
+ args << arel_table
178
+ args << predicate_builder if Rails.version >= '5.0.0'
179
+ end
172
180
  ActiveScaffold::Tableless::Relation.new(*args)
173
181
  end
182
+
183
+ if Rails.version >= '5.2'
184
+ def cached_find_by_statement(key, &block)
185
+ StatementCache.new(key, self, &block)
186
+ end
187
+ end
174
188
  end
175
189
 
176
190
  class StatementCache
177
- def initialize(key)
191
+ def initialize(key, model = nil)
178
192
  @key = key
193
+ @model = model
179
194
  end
180
195
 
181
- def execute(values, model, connection)
182
- model.where(@key => values)
196
+ if Rails.version < '5.2' # 5.0 and 5.1
197
+ def execute(values, model, connection)
198
+ model.where(@key => values)
199
+ end
200
+ else
201
+ def execute(values, connection)
202
+ @model.where(@key => values)
203
+ end
183
204
  end
184
205
  end
185
206
 
186
- unless Rails.version < '4.2'
187
- def self.columns_hash
188
- if self < ActiveScaffold::Tableless
189
- @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
190
- else
191
- super
192
- end
193
- end
194
- if Rails.version >= '5.0'
195
- def self.initialize_find_by_cache
196
- @find_by_statement_cache = {
197
- true => Hash.new { |h, k| h[k] = StatementCache.new(k) },
198
- false => Hash.new { |h, k| h[k] = StatementCache.new(k) }
199
- }
200
- end
207
+ def self.columns_hash
208
+ if self < ActiveScaffold::Tableless
209
+ @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
201
210
  else
202
- def self.initialize_find_by_cache
203
- self.find_by_statement_cache = Hash.new { |h, k| h[k] = StatementCache.new(k) }
204
- end
211
+ super
212
+ end
213
+ end
214
+ if Rails.version < '5.0' # 4.2.x
215
+ def self.initialize_find_by_cache
216
+ self.find_by_statement_cache = Hash.new { |h, k| h[k] = StatementCache.new(k) } # rubocop:disable Rails/DynamicFindBy
217
+ end
218
+ elsif Rails.version < '5.2' # 5.0 and 5.1
219
+ def self.initialize_find_by_cache
220
+ @find_by_statement_cache = {
221
+ true => Hash.new { |h, k| h[k] = StatementCache.new(k) },
222
+ false => Hash.new { |h, k| h[k] = StatementCache.new(k) }
223
+ }
205
224
  end
206
225
  end
207
226
 
@@ -236,11 +255,10 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
236
255
  end
237
256
 
238
257
  def self.execute_simple_calculation(relation, operation, column_name, distinct)
239
- if operation == 'count' && [relation.klass.primary_key, :all].include?(column_name)
240
- find_all(relation).size
241
- else
258
+ unless operation == 'count' && [relation.klass.primary_key, :all].include?(column_name)
242
259
  raise "self.execute_simple_calculation must be implemented in a Tableless model to support #{operation} #{column_name}#{' distinct' if distinct} columns"
243
260
  end
261
+ find_all(relation).size
244
262
  end
245
263
 
246
264
  def destroy
@@ -250,10 +268,8 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
250
268
  def _create_record #:nodoc:
251
269
  run_callbacks(:create) {}
252
270
  end
253
- alias create_record _create_record # for rails4 < 4.0.6, < 4.1.2
254
271
 
255
272
  def _update_record(*) #:nodoc:
256
273
  run_callbacks(:update) {}
257
274
  end
258
- alias update_record _update_record # for rails4 < 4.0.6, < 4.1.2
259
275
  end