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
@@ -19,7 +19,7 @@ module ActiveScaffold
19
19
  ActiveScaffold::Bridges.run_all
20
20
 
21
21
  # converts Foo::BarController to 'bar' and FooBarsController to 'foo_bar' and AddressController to 'address'
22
- model_id = to_s.split('::').last.sub(/Controller$/, '').pluralize.singularize.underscore unless model_id
22
+ model_id ||= to_s.split('::').last.sub(/Controller$/, '').pluralize.singularize.underscore
23
23
 
24
24
  # run the configuration
25
25
  @active_scaffold_config = ActiveScaffold::Config::Core.new(model_id)
@@ -33,14 +33,8 @@ module ActiveScaffold
33
33
  active_scaffold_config._load_action_columns
34
34
 
35
35
  # defines the attribute read methods on the model, so record.send() doesn't find protected/private methods instead
36
- klass = active_scaffold_config.model
37
- # Rails 4.0.4 has removed attribute_methods_generated,
38
- # and made define_attribute_methods threadsave to call multiple times.
39
- # Check for that here.
40
- if (Rails::VERSION::MAJOR == 4 && !klass.respond_to?(:attribute_methods_generated)) ||
41
- !klass.attribute_methods_generated?
42
- klass.define_attribute_methods
43
- end
36
+ # define_attribute_methods is safe to call multiple times since rails 4.0.4
37
+ active_scaffold_config.model.define_attribute_methods if active_scaffold_config.active_record?
44
38
  # include the rest of the code into the controller: the action core and the included actions
45
39
  module_eval do
46
40
  unless self < ActiveScaffold::Actions::Core
@@ -69,7 +63,13 @@ module ActiveScaffold
69
63
 
70
64
  module Prefixes
71
65
  define_method Rails.version < '4.2' ? 'parent_prefixes' : 'local_prefixes' do
72
- @local_prefixes ||= super() << 'active_scaffold_overrides'
66
+ @local_prefixes ||= begin
67
+ prefixes = super()
68
+ unless superclass.uses_active_scaffold? || prefixes.include?('active_scaffold_overrides')
69
+ prefixes << 'active_scaffold_overrides'
70
+ end
71
+ prefixes
72
+ end
73
73
  end
74
74
  end
75
75
 
@@ -100,7 +100,7 @@ module ActiveScaffold
100
100
  end
101
101
 
102
102
  def active_scaffold_controller_for_column(column, options = {})
103
- if column.polymorphic_association?
103
+ if column.association.polymorphic?
104
104
  :polymorph
105
105
  elsif options.include?(:controller)
106
106
  "#{options[:controller].to_s.camelize}Controller".constantize
@@ -117,11 +117,11 @@ module ActiveScaffold
117
117
  :controller => (controller == :polymorph ? controller : "/#{controller.controller_path}")
118
118
  options[:parameters] ||= {}
119
119
  options[:parameters].reverse_merge! :association => column.association.name
120
- if column.plural_association?
120
+ if column.association.collection?
121
121
  ActiveScaffold::DataStructures::ActionLink.new('index', options.merge(:refresh_on_close => true))
122
122
  else
123
123
  actions = controller.active_scaffold_config.actions unless controller == :polymorph
124
- actions ||= [:create, :update, :show]
124
+ actions ||= %i[create update show]
125
125
  column.actions_for_association_links.delete :new unless actions.include? :create
126
126
  column.actions_for_association_links.delete :edit unless actions.include? :update
127
127
  column.actions_for_association_links.delete :show unless actions.include? :show
@@ -206,7 +206,9 @@ module ActiveScaffold
206
206
  end
207
207
  end
208
208
  raise ActiveScaffold::ControllerNotFound, "#{controller} missing ActiveScaffold", caller unless controller.uses_active_scaffold?
209
- raise ActiveScaffold::ControllerNotFound, "ActiveScaffold on #{controller} is not for #{klass} model.", caller unless controller.active_scaffold_config.model.to_s == klass.to_s
209
+ unless controller.active_scaffold_config.model.to_s == klass.to_s
210
+ raise ActiveScaffold::ControllerNotFound, "ActiveScaffold on #{controller} is not for #{klass} model.", caller
211
+ end
210
212
  return controller
211
213
  end
212
214
  end
@@ -214,10 +216,29 @@ module ActiveScaffold
214
216
  end
215
217
 
216
218
  def self.column_type_cast(value, column)
219
+ if defined?(ActiveRecord) && ActiveRecord::ConnectionAdapters::Column === column
220
+ active_record_column_type_cast(value, column)
221
+ elsif defined?(Mongoid) && Mongoid::Fields::Standard === column
222
+ mongoid_column_type_cast(value, column)
223
+ else
224
+ value
225
+ end
226
+ end
227
+
228
+ def self.mongoid_column_type_cast(value, column)
229
+ column.type.evolve value
230
+ end
231
+
232
+ def self.active_record_column_type_cast(value, column)
217
233
  if Rails.version < '4.2'
218
234
  column.type_cast value
219
- else
235
+ elsif Rails.version < '5.0'
220
236
  column.type_cast_from_user value
237
+ elsif column.type.respond_to? :cast # jruby-jdbc and rails 5
238
+ column.type.cast value
239
+ else
240
+ cast_type = ActiveModel::Type.lookup column.type
241
+ cast_type ? cast_type.cast(value) : value
221
242
  end
222
243
  end
223
244
  end
@@ -18,7 +18,7 @@ module ActiveScaffold::DataStructures
18
18
  end
19
19
 
20
20
  def css_class
21
- @label.to_s.underscore.gsub /[^-_0-9a-zA-Z]/, '-'
21
+ @label.to_s.underscore.gsub(/[^-_0-9a-zA-Z]/, '-')
22
22
  end
23
23
 
24
24
  # this is so that array.delete and array.include?, etc., will work by column name
@@ -54,7 +54,7 @@ module ActiveScaffold::DataStructures
54
54
 
55
55
  def names
56
56
  if @columns
57
- collect_visible(:flatten => true) { |c| c.name }
57
+ collect_visible(:flatten => true, &:name)
58
58
  else
59
59
  names_without_auth_check
60
60
  end
@@ -76,7 +76,7 @@ module ActiveScaffold::DataStructures
76
76
  @set.each do |item|
77
77
  unless item.is_a?(ActiveScaffold::DataStructures::ActionColumns) || @columns.nil?
78
78
  item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
79
- next if self.skip_column?(item, options)
79
+ next if skip_column?(item, options)
80
80
  end
81
81
  if item.is_a? ActiveScaffold::DataStructures::ActionColumns
82
82
  if options[:flatten]
@@ -97,7 +97,7 @@ module ActiveScaffold::DataStructures
97
97
  @set.each do |item|
98
98
  unless item.is_a?(ActiveScaffold::DataStructures::ActionColumns) || @columns.nil?
99
99
  item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
100
- next if self.skip_column?(item, options)
100
+ next if skip_column?(item, options)
101
101
  end
102
102
  if item.is_a?(ActiveScaffold::DataStructures::ActionColumns) && options.key?(:flatten) && options[:flatten]
103
103
  columns += item.collect_visible(options, &proc)
@@ -132,23 +132,28 @@ module ActiveScaffold::DataStructures
132
132
  @action.class.name.demodulize.underscore
133
133
  end
134
134
 
135
- def constraint_columns_key
135
+ def columns_key
136
136
  "#{@action.core.model_id.to_s.underscore}-#{action_name}"
137
137
  end
138
138
 
139
139
  def constraint_columns=(columns)
140
140
  Thread.current[:constraint_columns] ||= {}
141
- Thread.current[:constraint_columns][constraint_columns_key] = columns
141
+ Thread.current[:constraint_columns][columns_key] = columns
142
142
  end
143
143
 
144
144
  def constraint_columns
145
145
  constraints = Thread.current[:constraint_columns]
146
- (constraints[constraint_columns_key] if constraints) || []
146
+ (constraints[columns_key] if constraints) || []
147
+ end
148
+
149
+ def unauthorized_columns=(columns)
150
+ Thread.current[:unauthorized_columns] ||= {}
151
+ Thread.current[:unauthorized_columns][columns_key] = columns
147
152
  end
148
153
 
149
- attr_writer :unauthorized_columns
150
154
  def unauthorized_columns
151
- @unauthorized_columns ||= []
155
+ Thread.current[:unauthorized_columns] ||= {}
156
+ Thread.current[:unauthorized_columns][columns_key] ||= []
152
157
  end
153
158
 
154
159
  def length
@@ -10,8 +10,8 @@ module ActiveScaffold::DataStructures
10
10
  self.inline = true
11
11
  self.method = :get
12
12
  self.crud_type = :delete if [:destroy].include?(action.try(:to_sym))
13
- self.crud_type = :create if [:create, :new].include?(action.try(:to_sym))
14
- self.crud_type = :update if [:edit, :update].include?(action.try(:to_sym))
13
+ self.crud_type = :create if %i[create new].include?(action.try(:to_sym))
14
+ self.crud_type = :update if %i[edit update].include?(action.try(:to_sym))
15
15
  self.crud_type ||= :read
16
16
  self.column = nil
17
17
  self.image = nil
@@ -21,7 +21,7 @@ module ActiveScaffold::DataStructures
21
21
  # apply quick properties
22
22
  options.each_pair do |k, v|
23
23
  setter = "#{k}="
24
- send(setter, v) if self.respond_to? setter
24
+ send(setter, v) if respond_to? setter
25
25
  end
26
26
  self.toggle = self.action.try(:to_sym) == :index && (parameters.present? || dynamic_parameters) unless options.include? :toggle
27
27
  end
@@ -90,7 +90,7 @@ module ActiveScaffold::DataStructures
90
90
  end
91
91
 
92
92
  # if the action uses a DHTML based (i.e. 2-phase) confirmation
93
- attr_accessor :dhtml_confirm
93
+ attr_reader :dhtml_confirm
94
94
  def dhtml_confirm=(value)
95
95
  @confirm = nil if value
96
96
  @dhtml_confirm = value
@@ -165,7 +165,6 @@ module ActiveScaffold::DataStructures
165
165
  # where the result of this action should insert in the display.
166
166
  # for :type => :collection, supported values are:
167
167
  # :top
168
- # :bottom
169
168
  # :replace (for updating the entire table)
170
169
  # false (no attempt at positioning)
171
170
  # for :type => :member, supported values are:
@@ -31,7 +31,7 @@ module ActiveScaffold::DataStructures
31
31
  link
32
32
  end
33
33
  end
34
- alias_method :<<, :add
34
+ alias << add
35
35
 
36
36
  def add_to_set(link)
37
37
  @set << link
@@ -84,13 +84,14 @@ module ActiveScaffold::DataStructures
84
84
 
85
85
  def delete_group(name)
86
86
  @set.each do |group|
87
+ next unless group.is_a?(ActiveScaffold::DataStructures::ActionLinks)
87
88
  if group.name == name
88
89
  @set.delete group
89
90
  break
90
91
  else
91
92
  group.delete_group(name)
92
93
  break
93
- end if group.is_a?(ActiveScaffold::DataStructures::ActionLinks)
94
+ end
94
95
  end
95
96
  end
96
97
 
@@ -121,7 +122,7 @@ module ActiveScaffold::DataStructures
121
122
  end
122
123
 
123
124
  def empty?
124
- @set.size == 0
125
+ @set.empty?
125
126
  end
126
127
 
127
128
  def subgroup(name, label = nil)
@@ -134,7 +135,7 @@ module ActiveScaffold::DataStructures
134
135
  group = ActiveScaffold::DataStructures::ActionLinks.new
135
136
  group.label = label || name
136
137
  group.name = name
137
- group.default_type = self.name == :root ? (name.to_sym if %w(member collection).include?(name.to_s)) : default_type
138
+ group.default_type = self.name == :root ? (name.to_sym if %w[member collection].include?(name.to_s)) : default_type
138
139
  add_to_set group
139
140
  end
140
141
  group
@@ -3,7 +3,7 @@ class ActiveScaffold::DataStructures::Actions
3
3
 
4
4
  def initialize(*args)
5
5
  @set = []
6
- add *args
6
+ add(*args)
7
7
  end
8
8
 
9
9
  def exclude(*args)
@@ -14,7 +14,7 @@ class ActiveScaffold::DataStructures::Actions
14
14
  def add(*args)
15
15
  args.each { |arg| @set << arg.to_sym unless @set.include? arg.to_sym }
16
16
  end
17
- alias_method :<<, :add
17
+ alias << add
18
18
 
19
19
  def each
20
20
  @set.each { |item| yield item }
@@ -0,0 +1,8 @@
1
+ module ActiveScaffold::DataStructures
2
+ module Association
3
+ autoload :Abstract, 'active_scaffold/data_structures/association/abstract.rb'
4
+ autoload :ActiveRecord, 'active_scaffold/data_structures/association/active_record.rb'
5
+ autoload :Mongoid, 'active_scaffold/data_structures/association/mongoid.rb'
6
+ autoload :ActiveMongoid, 'active_scaffold/data_structures/association/active_mongoid.rb'
7
+ end
8
+ end
@@ -0,0 +1,147 @@
1
+ module ActiveScaffold::DataStructures::Association
2
+ class Abstract
3
+ def initialize(association)
4
+ @association = association
5
+ end
6
+ attr_writer :reverse
7
+ delegate :name, :klass, :foreign_key, :==, to: :@association
8
+
9
+ def allow_join?
10
+ !polymorphic?
11
+ end
12
+
13
+ def belongs_to?
14
+ @association.macro == :belongs_to
15
+ end
16
+
17
+ def has_one?
18
+ @association.macro == :has_one
19
+ end
20
+
21
+ def has_many?
22
+ @association.macro == :has_many
23
+ end
24
+
25
+ def habtm?
26
+ @association.macro == :has_and_belongs_to_many
27
+ end
28
+
29
+ def singular?
30
+ !collection?
31
+ end
32
+
33
+ def through?
34
+ false
35
+ end
36
+
37
+ def polymorphic?
38
+ false
39
+ end
40
+
41
+ def readonly?
42
+ false
43
+ end
44
+
45
+ def through_reflection; end
46
+
47
+ def source_reflection; end
48
+
49
+ def scope; end
50
+
51
+ def respond_to_target?
52
+ false
53
+ end
54
+
55
+ def counter_cache_hack?
56
+ false
57
+ end
58
+
59
+ def quoted_table_name
60
+ raise "define quoted_table_name method in #{self.class.name} class"
61
+ end
62
+
63
+ def quoted_primary_key
64
+ raise "define quoted_primary_key method in #{self.class.name} class"
65
+ end
66
+
67
+ def reverse(klass = nil)
68
+ unless polymorphic? || defined?(@reverse)
69
+ @reverse ||= inverse || get_reverse.try(:name)
70
+ end
71
+ @reverse || (get_reverse(klass).try(:name) unless klass.nil?)
72
+ end
73
+
74
+ def inverse_for?(klass)
75
+ inverse_class = reverse_association(klass).try(:inverse_klass)
76
+ inverse_class.present? && (inverse_class == klass || klass < inverse_class)
77
+ end
78
+
79
+ def reverse_association(klass = nil)
80
+ assoc = if polymorphic?
81
+ get_reverse(klass) unless klass.nil?
82
+ else
83
+ return unless reverse_name = reverse(klass)
84
+ reflect_on_association(reverse_name)
85
+ end
86
+ self.class.new(assoc) if assoc
87
+ end
88
+
89
+ protected
90
+
91
+ def reflect_on_association(name)
92
+ @association.klass.reflect_on_association(name)
93
+ end
94
+
95
+ def get_reverse(klass = nil)
96
+ return nil if klass.nil? && polymorphic?
97
+
98
+ # name-based matching (association name vs self.active_record.to_s)
99
+ matches = reverse_matches(klass || self.klass)
100
+ if matches.length > 1
101
+ matches.select! do |assoc|
102
+ inverse_klass.name.underscore.include? assoc.name.to_s.pluralize.singularize
103
+ end
104
+ end
105
+
106
+ matches.first
107
+ end
108
+
109
+ def reverse_matches(klass)
110
+ associations = self.class.reflect_on_all_associations(klass)
111
+ # collect associations that point back to this model and use the same foreign_key
112
+ associations.each_with_object([]) do |assoc, reverse_matches|
113
+ reverse_matches << assoc if reverse_match? assoc
114
+ end
115
+ end
116
+
117
+ def reverse_match?(assoc)
118
+ return false if assoc == @association
119
+ return false unless assoc.polymorphic? || assoc.class_name == inverse_klass.try(:name)
120
+
121
+ if through?
122
+ reverse_through_match?(assoc)
123
+ elsif habtm?
124
+ reverse_habtm_match?(assoc)
125
+ else
126
+ reverse_direct_match?(assoc)
127
+ end
128
+ end
129
+
130
+ def reverse_through_match?(assoc); end
131
+
132
+ def reverse_habtm_match?(assoc)
133
+ assoc.macro == :has_and_belongs_to_many
134
+ end
135
+
136
+ def reverse_direct_match?(assoc)
137
+ # skip over has_and_belongs_to_many associations
138
+ return false if assoc.macro == :has_and_belongs_to_many
139
+
140
+ if foreign_key.is_a?(Array) || assoc.foreign_key.is_a?(Array) # composite_primary_keys
141
+ assoc.foreign_key == foreign_key
142
+ else
143
+ assoc.foreign_key.to_sym == foreign_key.to_sym
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,42 @@
1
+ module ActiveScaffold::DataStructures::Association
2
+ class ActiveMongoid < Mongoid
3
+ def self.reflect_on_all_associations(klass)
4
+ return [] unless klass.respond_to? :am_relations
5
+ klass.am_relations.values
6
+ end
7
+
8
+ def inverse_klass
9
+ as ? @association[:inverse_class_name].constantize : super
10
+ end
11
+
12
+ def allow_join?
13
+ false
14
+ end
15
+
16
+ def belongs_to?
17
+ %i[belongs_to_record belongs_to_document].include?(@association.macro)
18
+ end
19
+
20
+ def has_one?
21
+ %i[has_one_record has_one_document].include?(@association.macro)
22
+ end
23
+
24
+ def has_many?
25
+ %i[has_many_records has_many_documents].include?(@association.macro)
26
+ end
27
+
28
+ def collection?
29
+ %i[has_many_documents has_many_records].include?(@association.macro)
30
+ end
31
+
32
+ def table_name
33
+ @association.klass < ActiveRecord::Base ? @association.klass.table_name : super
34
+ end
35
+
36
+ protected
37
+
38
+ def reflect_on_association(name)
39
+ @association.klass.reflect_on_am_association(name)
40
+ end
41
+ end
42
+ end