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.
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
@@ -1,80 +1,84 @@
1
- ru:
2
- active_scaffold:
3
- ? "!="
4
- : "!="
5
- <: <
6
- <=: <=
7
- ? ">"
8
- : ">"
9
- ? ">="
10
- : ">="
1
+ ru:
2
+ active_scaffold:
3
+ "!=": "!="
4
+ "<": "<"
5
+ "<=": "<="
6
+ "=": "="
7
+ ">": ">"
8
+ ">=": ">="
11
9
  _select_: "- выбрать -"
12
10
  _to_: " to "
13
- add: "Добавить запись"
14
- add_existing: "Добавить существующую запись"
11
+ add: Добавить запись
12
+ add_existing: Добавить существующую запись
15
13
  add_existing_model: "%{model}: добавить существующую запись"
16
- are_you_sure_to_delete: "Удалить %{label}?"
14
+ apply: Применить
15
+ are_you_sure_to_delete: Удалить %{label}?
17
16
  average: Среднее
18
- begins_with: "Начинается с"
19
- between: "В интервале"
17
+ begins_with: Начинается с
18
+ between: В интервале
20
19
  cancel: Отмена
21
- cant_destroy_record: "Запись %{record} не может быть удалена"
22
- click_to_edit: "Нажмите для редактирования"
23
- click_to_reset: "Нажмите для сброса"
20
+ cant_destroy_record: Запись %{record} не может быть удалена
21
+ changes:
22
+ click_to_edit: Нажмите для редактирования
23
+ click_to_reset: Нажмите для сброса
24
24
  close: Закрыть
25
+ config_list: Настройки списка
26
+ config_list_model: "%{model}: настройки списка"
25
27
  contains: Содержит
26
28
  create: Создать
27
29
  create_another: "%{model}: Создать другую запись"
28
- create_apply: Создать и продолжить
30
+ create_apply:
29
31
  create_model: "%{model}: создать запись"
30
- create_new: "Создать новую запись"
32
+ create_new: Создать новую запись
31
33
  created_model: "%{model}: запись создана"
32
34
  customize: Настроить
33
- date_picker_options:
35
+ date_picker_options:
34
36
  firstDay: 1
35
37
  isRTL: false
36
38
  showMonthAfterYear: false
37
39
  weekHeader: Нед.
38
- datetime_picker_options:
39
- closeText: ~
40
- currentText: ~
41
- timeText: ~
40
+ datetime_picker_options:
41
+ closeText: Закрыть
42
+ currentText: Текущее время
43
+ timeText:
42
44
  days: дней
43
45
  delete: Удалить
44
46
  deleted_model: "%{model}: запись удалена"
47
+ deleted_records:
45
48
  delimiter: Разделитель
46
49
  download: Загрузить
47
50
  edit: Изменить
48
- ends_with: "Оканчивается на"
49
- error_500: "500 ошибка сервера"
50
- errors:
51
- template:
52
- body: "Проблемы возникли со следующими полями:"
53
- header:
51
+ ends_with: Оканчивается на
52
+ error_500: 500 ошибка сервера
53
+ errors:
54
+ template:
55
+ body: 'Проблемы возникли со следующими полями:'
56
+ header:
54
57
  few: "%{model}: сохранение не удалось из-за %{count} ошибок"
55
58
  many: "%{model}: сохранение не удалось из-за %{count} ошибок"
56
59
  one: "%{model}: сохранение не удалось из-за %{count} ошибки"
57
60
  other: "%{model}: сохранение не удалось из-за %{count} ошибки"
58
61
  export: Экспорт
59
- ? "false"
60
- : Нет
61
- filtered: (Найденное)
62
- found:
62
+ 'false': Нет
63
+ filtered: "(Найденное)"
64
+ found:
63
65
  few: записи
64
66
  many: записей
65
67
  one: запись
66
68
  other: записи
67
69
  future: Будущие
68
- hide: (Скрыть)
70
+ group_by:
71
+ grouped_by:
72
+ hide: "(Скрыть)"
69
73
  hours: часов
70
- human_conditions:
74
+ human_conditions:
71
75
  association: "%{column} = %{value}"
72
76
  boolean: "%{column} = %{value}"
73
77
  inplace_edit_handle: "--"
74
- internal_error: "Внутренняя ошибка"
78
+ internal_error: Внутренняя ошибка
75
79
  live_search: Поиск
76
80
  loading: Загрузка…
77
- mark_all_records: "Отметить все"
81
+ mark_all_records: Отметить все
78
82
  maximum: Максимум
79
83
  minimum: Минимум
80
84
  minutes: минут
@@ -82,62 +86,69 @@ ru:
82
86
  nested_for_model: "%{parent_model} / %{nested_model}"
83
87
  nested_of_model: "%{nested_model} @ %{parent_model}"
84
88
  next: Следующее
85
- next_month: "В следующем месяце"
86
- next_week: "На следующей неделе"
87
- next_year: "В следующем году"
88
- no_authorization_for_action: "Нет прав на выполнение действия \"%{action}\""
89
- no_entries: "Нет записей"
90
- no_options: "Нет вариантов"
91
- not_null: "Не пусто"
92
- ? "null"
93
- : Пусто
94
- omit_header: "Пропустить заголовок"
95
- optional_attributes: "Дополнительные настройки"
89
+ next_month: В следующем месяце
90
+ next_week: На следующей неделе
91
+ next_year: В следующем году
92
+ no_authorization_for_action: Нет прав на выполнение действия "%{action}"
93
+ no_color:
94
+ no_entries: Нет записей
95
+ no_group:
96
+ no_options: Нет вариантов
97
+ not_null: Не пусто
98
+ 'null': Пусто
99
+ omit_header: Пропустить заголовок
100
+ optional_attributes: Дополнительные настройки
96
101
  options: Настройки
97
102
  past: Прошедшие
98
103
  pdf: PDF
99
- prev_month: "В прошлом месяце"
100
- prev_week: "На прошлой неделе"
101
- prev_year: "В прошлом году"
104
+ prev_month: В прошлом месяце
105
+ prev_week: На прошлой неделе
106
+ prev_year: В прошлом году
102
107
  previous: Предыдущее
103
108
  print: Печать
104
109
  range: Интервал
105
- record_not_saved: "Запись не может быть сохранена из-за неизвестной ошибки"
106
- records_marked:
107
- few: "Отмечено %{count} записи"
108
- many: "Отмечено %{count} записей"
109
- one: "Отмечена 1 запись"
110
- other: "Отмечено %{count} записи"
110
+ record_not_saved: Запись не может быть сохранена из-за неизвестной ошибки
111
+ records_marked:
112
+ few: Отмечено %{count} записи
113
+ many: Отмечено %{count} записей
114
+ one: Отмечена 1 запись
115
+ other: Отмечено %{count} записи
111
116
  refresh: Обновить
112
117
  remove: Удалить
113
- remove_file: "Удалить или заменить файл"
114
- replace_existing: "Заменить существующим"
115
- replace_with_new: "Заменить новым"
118
+ remove_file: Удалить или заменить файл
119
+ replace_existing: Заменить существующим
120
+ replace_with_new: Заменить новым
116
121
  reset: Сброс
117
122
  revisions_for_model: "%{model}: редакции"
118
123
  saving: Сохранение…
119
124
  search: Поиск
120
- search_terms: "Ключевые слова"
125
+ search_terms: Ключевые слова
121
126
  seconds: секунд
122
127
  show: Показать
123
- show_block: (Показать)
128
+ show_block: "(Показать)"
124
129
  show_model: "%{model}: показать запись"
125
130
  sum: Сумма
126
- this_month: "В этом месяце"
127
- this_week: "На этой неделе"
128
- this_year: "В этом году"
131
+ this_month: В этом месяце
132
+ this_week: На этой неделе
133
+ this_year: В этом году
129
134
  today: Сегодня
130
135
  tomorrow: Завтра
131
- ? "true"
132
- : Да
133
- update: "Обновить запись"
134
- update_apply: Применить
136
+ 'true': Да
137
+ update: Обновить запись
138
+ update_apply:
135
139
  update_model: "%{model}: обновить запись"
136
140
  updated_model: "%{model}: запись обновлена"
137
- version_inconsistency: "Эта запись была обновлена с того момента, как вы начали ее редактировать"
141
+ version_inconsistency: Эта запись была обновлена с того момента, как вы начали ее редактировать
138
142
  weeks: недель
139
143
  years: лет
140
144
  yesterday: Вчера
141
- time:
142
- formats:
145
+ date:
146
+ formats:
147
+ month:
148
+ quarter:
149
+ week:
150
+ year_month:
151
+ year_quarter:
152
+ time:
153
+ formats:
143
154
  picker: "%a, %d %b %Y %H:%M:%S"
@@ -8,6 +8,7 @@ module ActiveScaffold
8
8
  autoload :DelayedSetup, 'active_scaffold/delayed_setup'
9
9
  autoload :Finder, 'active_scaffold/finder'
10
10
  autoload :MarkedModel, 'active_scaffold/marked_model'
11
+ autoload :OrmChecks, 'active_scaffold/orm_checks'
11
12
  autoload :RespondsToParent, 'active_scaffold/responds_to_parent'
12
13
  autoload :Tableless, 'active_scaffold/tableless'
13
14
  autoload :Version, 'active_scaffold/version'
@@ -91,5 +92,7 @@ module ActiveScaffold
91
92
  end
92
93
  end
93
94
  require 'active_scaffold/engine'
95
+ require 'ice_nine'
96
+ require 'ice_nine/core_ext/object'
94
97
  # TODO: clean up extensions. some could be organized for autoloading, and others could be removed entirely.
95
98
  Dir["#{File.dirname __FILE__}/active_scaffold/extensions/*.rb"].each { |file| require file }
@@ -3,9 +3,9 @@ module ActiveScaffold::Actions
3
3
  def self.included(base)
4
4
  unless base < InstanceMethods
5
5
  base.send :include, InstanceMethods
6
- base.before_filter :search_authorized_filter, :only => :show_search
7
- base.before_filter :store_search_params_into_session, :only => [:index]
8
- base.before_filter :do_search, :only => [:index]
6
+ base.before_action :search_authorized_filter, :only => :show_search
7
+ base.before_action :store_search_params_into_session, :only => [:index]
8
+ base.before_action :do_search, :only => [:index]
9
9
  base.helper_method :search_params
10
10
  end
11
11
  end
@@ -17,8 +17,7 @@ module ActiveScaffold::Actions
17
17
 
18
18
  protected
19
19
 
20
- def do_search
21
- end
20
+ def do_search; end
22
21
 
23
22
  def search_partial
24
23
  @_search_partial ||=
@@ -29,12 +28,17 @@ module ActiveScaffold::Actions
29
28
  end
30
29
  end
31
30
 
31
+ def permitted_search_params
32
+ params_hash params[:search]
33
+ end
34
+
32
35
  def store_search_params_into_session
33
36
  if active_scaffold_config.store_user_settings
34
- active_scaffold_session_storage['search'] = params.delete :search if params[:search]
37
+ active_scaffold_session_storage['search'] = permitted_search_params if params[:search]
35
38
  else
36
- @search_params = params.delete :search
39
+ @search_params = permitted_search_params
37
40
  end
41
+ params.delete :search
38
42
  end
39
43
 
40
44
  def search_params
@@ -2,15 +2,17 @@ module ActiveScaffold::Actions
2
2
  module Core
3
3
  def self.included(base)
4
4
  base.class_eval do
5
- before_filter :handle_user_settings
6
- before_filter :check_input_device
7
- before_filter :register_constraints_with_action_columns, :unless => :nested?
8
- after_filter :clear_flashes
9
- after_filter :clear_storage
5
+ before_action :set_vary_accept_header
6
+ before_action :handle_user_settings
7
+ before_action :check_input_device
8
+ before_action :register_constraints_with_action_columns, :unless => :nested?
9
+ after_action :clear_flashes
10
+ after_action :clear_storage
10
11
  rescue_from ActiveScaffold::RecordNotAllowed, ActiveScaffold::ActionNotAllowed, :with => :deny_access
11
12
  end
12
13
  base.helper_method :successful?
13
14
  base.helper_method :nested?
15
+ base.helper_method :grouped_search?
14
16
  base.helper_method :embedded?
15
17
  base.helper_method :loading_embedded?
16
18
  base.helper_method :calculate_query
@@ -18,6 +20,7 @@ module ActiveScaffold::Actions
18
20
  base.helper_method :touch_device?
19
21
  base.helper_method :hover_via_click?
20
22
  end
23
+
21
24
  def render_field
22
25
  if request.get?
23
26
  render_field_for_inplace_editing
@@ -33,7 +36,7 @@ module ActiveScaffold::Actions
33
36
  protected
34
37
 
35
38
  def loading_embedded?
36
- @loading_embedded ||= params.delete(:embedded)
39
+ @loading_embedded ||= active_scaffold_embedded_params.delete(:loading)
37
40
  end
38
41
 
39
42
  def embedded?
@@ -44,6 +47,10 @@ module ActiveScaffold::Actions
44
47
  false
45
48
  end
46
49
 
50
+ def grouped_search?
51
+ false
52
+ end
53
+
47
54
  def render_field_for_inplace_editing
48
55
  @column = active_scaffold_config.columns[params[:update_column]]
49
56
  @record = find_if_allowed(params[:id], :crud_type => :update, :column => params[:update_column])
@@ -65,13 +72,13 @@ module ActiveScaffold::Actions
65
72
  else
66
73
  updated_record_with_column(@column, params.delete(:value), @scope)
67
74
  end
68
- set_parent(@record) if params[:parent_controller] && @scope
75
+ set_parent(@record) if main_form_controller && @scope
69
76
  after_render_field(@record, @column)
70
77
  end
71
78
 
72
79
  def updated_record_with_form(columns, attributes, scope)
73
80
  if attributes && scope
74
- attributes = scope.gsub('[', '').split(']').inject(attributes) { |h, idx| h[idx] }
81
+ attributes = scope.delete('[').split(']').inject(attributes) { |h, idx| h[idx] }
75
82
  id = attributes[:id]
76
83
  else
77
84
  id = params[:id]
@@ -88,7 +95,7 @@ module ActiveScaffold::Actions
88
95
  end
89
96
 
90
97
  def updated_record_with_column(column, value, scope)
91
- record = params[:id] ? find_if_allowed(params[:id], :read).dup : new_model
98
+ record = params[:id] ? copy_attributes(find_if_allowed(params[:id], :read)) : new_model
92
99
  apply_constraints_to_record(record) unless scope || params[:id]
93
100
  value = column_value_from_param_value(record, column, value)
94
101
  record.send "#{column.name}=", value
@@ -96,39 +103,55 @@ module ActiveScaffold::Actions
96
103
  record
97
104
  end
98
105
 
106
+ def subform_child_association
107
+ params[:child_association].presence || (@scope.split(']').first.sub(/^\[/, '').presence if @scope)
108
+ end
109
+
110
+ def parent_controller_name
111
+ "#{params[:parent_controller].camelize}Controller"
112
+ end
113
+
99
114
  def set_parent(record)
100
- controller = "#{params[:parent_controller].camelize}Controller".constantize
101
- parent_model = controller.active_scaffold_config.model
102
- child_association = params[:child_association].presence || @scope.split(']').first.sub(/^\[/, '')
103
- association = parent_model.reflect_on_association(child_association.to_sym).try(:reverse)
115
+ cfg = main_form_controller.active_scaffold_config
116
+ association = cfg.columns[subform_child_association].try(:association).try(:reverse_association)
104
117
  return if association.nil?
105
118
 
119
+ parent_model = cfg.model
106
120
  parent = parent_model.new
107
- copy_attributes(parent_model.find(params[:parent_id]), parent) if params[:parent_id]
121
+ copy_attributes(find_if_allowed(params[:parent_id], :read, parent_model), parent) if params[:parent_id]
108
122
  parent.id = params[:parent_id]
109
- parent = update_record_from_params(parent, active_scaffold_config_for(parent_model).send(params[:parent_id] ? :update : :create).columns, params[:record], true) if @column.send_form_on_update_column
123
+ parent = update_record_from_params(parent, cfg.send(params[:parent_id] ? :update : :create).columns, params[:record], true) if @column.send_form_on_update_column
110
124
  apply_constraints_to_record(parent) unless params[:parent_id]
111
- if record.class.reflect_on_association(association).collection?
112
- record.send(association) << parent
125
+ if association.collection?
126
+ record.send(association.name) << parent
113
127
  else
114
- record.send("#{association}=", parent)
128
+ record.send("#{association.name}=", parent)
129
+ end
130
+
131
+ if params[:nested] # form in nested scaffold, set nested parent_record to parent
132
+ nested = ActiveScaffold::DataStructures::NestedInfo.get(parent.class, params.delete(:nested))
133
+ if nested.child_association
134
+ apply_constraints_to_record(parent, constraints: {nested.child_association.name => nested.parent_id})
135
+ end
115
136
  end
137
+ parent
116
138
  end
117
139
 
118
140
  def copy_attributes(orig, dst = nil)
119
141
  dst ||= orig.class.new
120
- attributes = orig.attributes
121
- if orig.class.respond_to?(:accessible_attributes) && orig.class.accessible_attributes.present?
122
- attributes.each { |attr, value| dst.send :write_attribute, attr, value if orig.class.accessible_attributes.deny? attr }
123
- attributes = attributes.slice(*orig.class.accessible_attributes)
124
- elsif orig.class.respond_to? :protected_attributes
125
- orig.class.protected_attributes.each { |attr| dst.send :write_attribute, attr, orig[attr] if attr.present? }
126
- attributes = attributes.except(*orig.class.protected_attributes)
127
- end
128
- dst.attributes = attributes
142
+ orig.attributes.each { |attr, value| dst.send :write_attribute, attr, value }
129
143
  dst
130
144
  end
131
145
 
146
+ def parent_sti_controller
147
+ return unless params[:parent_sti]
148
+ unless defined? @parent_sti_controller
149
+ controller = look_for_parent_sti_controller
150
+ @parent_sti_controller = controller.controller_path == params[:parent_sti] ? controller : false
151
+ end
152
+ @parent_sti_controller
153
+ end
154
+
132
155
  # override this method if you want to do something after render_field
133
156
  def after_render_field(record, column); end
134
157
 
@@ -149,7 +172,7 @@ module ActiveScaffold::Actions
149
172
  end
150
173
 
151
174
  def default_formats
152
- [:html, :js, :json, :xml]
175
+ %i[html js json xml]
153
176
  end
154
177
 
155
178
  # Returns true if the client accepts one of the MIME types passed to it
@@ -192,12 +215,15 @@ module ActiveScaffold::Actions
192
215
  end
193
216
 
194
217
  def successful=(val)
195
- @successful = (val) ? true : false
218
+ @successful = val ? true : false
196
219
  end
197
220
 
198
221
  # Redirect to the main page (override if the ActiveScaffold is used as a component on another controllers page) for Javascript degradation
199
222
  def return_to_main
200
- redirect_to main_path_to_return
223
+ options = main_path_to_return
224
+ # use url_for in case main_path_to_return returns Hash with status param,
225
+ # which would be interpreted as status option to redirect_to instead of url param
226
+ redirect_to options.is_a?(Hash) ? url_for(options) : options
201
227
  end
202
228
 
203
229
  # Overide this method on your controller to provide model with named scopes
@@ -210,37 +236,43 @@ module ActiveScaffold::Actions
210
236
  @conditions_from_params ||= begin
211
237
  conditions = {}
212
238
  params.except(:controller, :action, :page, :sort, :sort_direction, :format, :id).each do |key, value|
213
- column = active_scaffold_config.model.columns_hash[key.to_s]
239
+ column = active_scaffold_config._columns_hash[key.to_s]
214
240
  next unless column
215
241
  key = key.to_sym
216
- not_string = [:string, :text].exclude?(column.type)
242
+ not_string = %i[string text].exclude?(column.type)
217
243
  next if active_scaffold_constraints[key]
218
244
  next if nested? && nested.param_name == key
245
+
246
+ range = %i[date datetime].include?(column.type) && value.is_a?(String) && value.scan('..').size == 1
247
+ value = value.split('..') if range
219
248
  conditions[key] =
220
249
  if value.is_a?(Array)
221
250
  value.map { |v| v == '' && not_string ? nil : ActiveScaffold::Core.column_type_cast(v, column) }
222
251
  else
223
252
  value == '' && not_string ? nil : ActiveScaffold::Core.column_type_cast(value, column)
224
253
  end
254
+ conditions[key] = Range.new(*conditions[key]) if range
225
255
  end
226
256
  conditions
227
257
  end
228
258
  end
229
259
 
230
260
  def new_model
231
- model = beginning_of_chain
232
- if nested? && nested.association && nested.association.collection? && model.columns_hash[column = model.inheritance_column]
261
+ relation = beginning_of_chain
262
+ config = active_scaffold_config_for(relation.klass) if nested? && nested.plural_association?
263
+ if config && config._columns_hash[column = relation.klass.inheritance_column]
233
264
  model_name = params.delete(column) # in new action inheritance_column must be in params
234
- model_name ||= params[:record].delete(column) unless params[:record].blank? # in create action must be inside record key
265
+ model_name ||= params[:record].delete(column) if params[:record].present? # in create action must be inside record key
235
266
  model_name = model_name.camelize if model_name
236
267
  model_name ||= active_scaffold_config.model.name
237
268
  build_options = {column.to_sym => model_name} if model_name
238
269
  end
239
- model.respond_to?(:build) ? model.build(build_options || {}) : model.new
270
+ relation.respond_to?(:build) ? relation.build(build_options || {}) : relation.new
240
271
  end
241
272
 
242
273
  def get_row(crud_type_or_security_options = :read)
243
- klass = beginning_of_chain.preload(active_scaffold_preload)
274
+ klass = beginning_of_chain
275
+ klass = klass.preload(active_scaffold_preload) unless active_scaffold_config.mongoid?
244
276
  @record = find_if_allowed(params[:id], crud_type_or_security_options, klass)
245
277
  end
246
278
 
@@ -255,9 +287,17 @@ module ActiveScaffold::Actions
255
287
  session[session_index]
256
288
  end
257
289
 
290
+ def active_scaffold_embedded_params
291
+ params[:embedded] || {}
292
+ end
293
+
258
294
  def clear_storage
259
295
  session_index = active_scaffold_session_storage_key
260
- session.delete(session_index) unless session[session_index].present?
296
+ session.delete(session_index) if session[session_index].blank?
297
+ end
298
+
299
+ def set_vary_accept_header
300
+ response.headers['Vary'] = 'Accept'
261
301
  end
262
302
 
263
303
  # at some point we need to pass the session and params into config. we'll just take care of that before any particular action occurs by passing those hashes off to the UserSettings class of each action.
@@ -271,13 +311,15 @@ module ActiveScaffold::Actions
271
311
  end
272
312
 
273
313
  def check_input_device
274
- if request.env['HTTP_USER_AGENT'] && request.env['HTTP_USER_AGENT'][/(iPhone|iPod|iPad)/i]
275
- session[:input_device_type] = 'TOUCH'
276
- session[:hover_supported] = false
277
- else
278
- session[:input_device_type] = 'MOUSE'
279
- session[:hover_supported] = true
280
- end if session[:input_device_type].nil?
314
+ if session[:input_device_type].nil?
315
+ if request.env['HTTP_USER_AGENT'] && request.env['HTTP_USER_AGENT'][/(iPhone|iPod|iPad)/i]
316
+ session[:input_device_type] = 'TOUCH'
317
+ session[:hover_supported] = false
318
+ else
319
+ session[:input_device_type] = 'MOUSE'
320
+ session[:hover_supported] = true
321
+ end
322
+ end
281
323
  end
282
324
 
283
325
  def touch_device?
@@ -288,6 +330,22 @@ module ActiveScaffold::Actions
288
330
  session[:hover_supported] == false
289
331
  end
290
332
 
333
+ def params_hash?(value)
334
+ value.is_a?(Hash) || controller_params?(value)
335
+ end
336
+
337
+ def controller_params?(value)
338
+ value.is_a?(::ActionController::Parameters)
339
+ end
340
+
341
+ def params_hash(value)
342
+ if controller_params?(value)
343
+ Rails.version < '4.2' ? value.clone.permit! : value.to_unsafe_h.with_indifferent_access
344
+ else
345
+ value
346
+ end
347
+ end
348
+
291
349
  # call this method in your action_link action to simplify processing of actions
292
350
  # eg for member action_link :fire
293
351
  # process_action_link_action do |record|
@@ -362,11 +420,11 @@ module ActiveScaffold::Actions
362
420
  end
363
421
 
364
422
  def virtual_columns(columns)
365
- columns.reject { |col| active_scaffold_config.model.columns_hash[col.to_s] || active_scaffold_config.model.reflect_on_association(col) }
423
+ columns.reject { |col| active_scaffold_config.model.columns_hash[col.to_s] || active_scaffold_config.columns[col].try(:association) }
366
424
  end
367
425
 
368
426
  def association_columns(columns)
369
- columns.select { |col| active_scaffold_config.model.reflect_on_association(col) }
427
+ columns.select { |col| active_scaffold_config.columns[col].try(:association) }
370
428
  end
371
429
 
372
430
  private
@@ -392,5 +450,19 @@ module ActiveScaffold::Actions
392
450
  (default_formats + active_scaffold_config.formats).uniq
393
451
  end
394
452
  end
453
+
454
+ def look_for_parent_sti_controller
455
+ klass = self.class.active_scaffold_config.model
456
+ loop do
457
+ klass = klass.superclass
458
+ controller = self.class.active_scaffold_controller_for(klass)
459
+ cfg = controller.active_scaffold_config if controller.uses_active_scaffold?
460
+ next unless cfg && cfg.add_sti_create_links?
461
+ return controller if cfg.sti_children.map(&:to_s).include? self.class.active_scaffold_config.model.name.underscore
462
+ end
463
+ rescue ActiveScaffold::ControllerNotFound => ex
464
+ logger.warn "#{ex.message} looking for parent_sti of #{self.class.active_scaffold_config.model.name}"
465
+ nil
466
+ end
395
467
  end
396
468
  end