active_scaffold 3.2.20 → 3.3.0.rc

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 (152) hide show
  1. data/CHANGELOG +19 -13
  2. data/README +66 -0
  3. data/app/assets/javascripts/jquery/active_scaffold.js +156 -113
  4. data/app/assets/javascripts/jquery/active_scaffold_chosen.js +11 -0
  5. data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +0 -1
  6. data/app/assets/javascripts/jquery/jquery.editinplace.js +132 -128
  7. data/app/assets/javascripts/prototype/active_scaffold.js +68 -25
  8. data/{frontends/default/views/_horizontal_subform_footer.html.erb → app/assets/javascripts/prototype/active_scaffold_chosen.js} +0 -0
  9. data/app/assets/stylesheets/active_scaffold_colors.css.scss +8 -1
  10. data/app/assets/stylesheets/active_scaffold_layout.css +14 -8
  11. data/{frontends/default/views → app/views/active_scaffold_overrides}/_add_existing_form.html.erb +0 -0
  12. data/{frontends/default/views → app/views/active_scaffold_overrides}/_base_form.html.erb +0 -0
  13. data/{frontends/default/views → app/views/active_scaffold_overrides}/_create_form.html.erb +0 -0
  14. data/{frontends/default/views → app/views/active_scaffold_overrides}/_create_form_on_list.html.erb +0 -0
  15. data/{frontends/default/views → app/views/active_scaffold_overrides}/_field_search.html.erb +0 -0
  16. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form.html.erb +0 -0
  17. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_association.html.erb +8 -3
  18. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_association_footer.html.erb +5 -4
  19. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +85 -0
  20. data/app/views/active_scaffold_overrides/_form_attribute.html.erb +23 -0
  21. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_hidden_attribute.html.erb +0 -0
  22. data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_messages.html.erb +0 -0
  23. data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +12 -0
  24. data/app/views/active_scaffold_overrides/_horizontal_subform_footer.html.erb +0 -0
  25. data/{frontends/default/views → app/views/active_scaffold_overrides}/_horizontal_subform_header.html.erb +3 -2
  26. data/{frontends/default/views → app/views/active_scaffold_overrides}/_human_conditions.html.erb +0 -0
  27. data/app/views/active_scaffold_overrides/_list.html.erb +35 -0
  28. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_calculations.html.erb +0 -0
  29. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_column_headings.html.erb +0 -0
  30. data/app/views/active_scaffold_overrides/_list_header.html.erb +8 -0
  31. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_inline_adapter.html.erb +0 -0
  32. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_messages.html.erb +4 -4
  33. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_pagination.html.erb +0 -0
  34. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_pagination_links.html.erb +0 -0
  35. data/app/views/active_scaffold_overrides/_list_record.html.erb +30 -0
  36. data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_with_header.html.erb +0 -0
  37. data/{frontends/default/views → app/views/active_scaffold_overrides}/_messages.html.erb +0 -0
  38. data/app/views/active_scaffold_overrides/_refresh_list.js.erb +1 -0
  39. data/{frontends/default/views → app/views/active_scaffold_overrides}/_render_field.js.erb +9 -1
  40. data/{frontends/default/views → app/views/active_scaffold_overrides}/_row.html.erb +0 -0
  41. data/{frontends/default/views → app/views/active_scaffold_overrides}/_search.html.erb +0 -0
  42. data/{frontends/default/views → app/views/active_scaffold_overrides}/_search_attribute.html.erb +0 -0
  43. data/{frontends/default/views → app/views/active_scaffold_overrides}/_show.html.erb +0 -0
  44. data/{frontends/default/views → app/views/active_scaffold_overrides}/_show_columns.html.erb +0 -0
  45. data/app/views/active_scaffold_overrides/_update_actions.html.erb +9 -0
  46. data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_calculations.js.erb +0 -0
  47. data/app/views/active_scaffold_overrides/_update_column.js.erb +16 -0
  48. data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_form.html.erb +0 -0
  49. data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_messages.js.erb +0 -0
  50. data/app/views/active_scaffold_overrides/_vertical_subform.html.erb +8 -0
  51. data/{frontends/default/views → app/views/active_scaffold_overrides}/action_confirmation.html.erb +0 -0
  52. data/{frontends/default/views → app/views/active_scaffold_overrides}/add_existing.js.erb +0 -0
  53. data/{frontends/default/views → app/views/active_scaffold_overrides}/add_existing_form.html.erb +0 -0
  54. data/{frontends/default/views → app/views/active_scaffold_overrides}/create.html.erb +0 -0
  55. data/{frontends/default/views → app/views/active_scaffold_overrides}/delete.html.erb +0 -0
  56. data/{frontends/default/views → app/views/active_scaffold_overrides}/destroy.js.erb +0 -0
  57. data/{frontends/default/views → app/views/active_scaffold_overrides}/edit_associated.js.erb +1 -1
  58. data/{frontends/default/views → app/views/active_scaffold_overrides}/field_search.html.erb +0 -0
  59. data/{frontends/default/views → app/views/active_scaffold_overrides}/form_messages.js.erb +0 -0
  60. data/{frontends/default/views → app/views/active_scaffold_overrides}/list.html.erb +0 -0
  61. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_action_update.js.erb +3 -3
  62. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_create.js.erb +1 -1
  63. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_mark.js.erb +0 -0
  64. data/{frontends/default/views → app/views/active_scaffold_overrides}/on_update.js.erb +4 -4
  65. data/{frontends/default/views → app/views/active_scaffold_overrides}/render_field.js.erb +0 -0
  66. data/{frontends/default/views → app/views/active_scaffold_overrides}/row.js.erb +1 -1
  67. data/{frontends/default/views → app/views/active_scaffold_overrides}/search.html.erb +0 -0
  68. data/{frontends/default/views → app/views/active_scaffold_overrides}/show.html.erb +0 -0
  69. data/{frontends/default/views → app/views/active_scaffold_overrides}/update.html.erb +1 -1
  70. data/app/views/active_scaffold_overrides/update_column.js.erb +26 -0
  71. data/{frontends/default/views → app/views/active_scaffold_overrides}/update_row.js.erb +0 -0
  72. data/config/locales/de.yml +1 -0
  73. data/config/locales/en.yml +1 -0
  74. data/config/locales/es.yml +1 -0
  75. data/config/locales/fr.yml +1 -0
  76. data/config/locales/hu.yml +1 -0
  77. data/config/locales/ja.yml +1 -0
  78. data/config/locales/ru.yml +1 -0
  79. data/lib/active_scaffold.rb +14 -26
  80. data/lib/active_scaffold/actions/core.rb +14 -11
  81. data/lib/active_scaffold/actions/create.rb +3 -3
  82. data/lib/active_scaffold/actions/delete.rb +3 -0
  83. data/lib/active_scaffold/actions/list.rb +9 -6
  84. data/lib/active_scaffold/actions/mark.rb +1 -1
  85. data/lib/active_scaffold/actions/nested.rb +8 -6
  86. data/lib/active_scaffold/actions/show.rb +6 -1
  87. data/lib/active_scaffold/actions/update.rb +39 -19
  88. data/lib/active_scaffold/active_record_permissions.rb +29 -12
  89. data/lib/active_scaffold/attribute_params.rb +14 -7
  90. data/lib/active_scaffold/bridges/calendar_date_select.rb +1 -1
  91. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +1 -2
  92. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
  93. data/lib/active_scaffold/bridges/chosen.rb +14 -0
  94. data/lib/active_scaffold/bridges/chosen/helpers.rb +48 -0
  95. data/lib/active_scaffold/bridges/date_picker/helper.rb +7 -6
  96. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +1 -1
  97. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +1 -1
  98. data/lib/active_scaffold/bridges/file_column.rb +1 -1
  99. data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +1 -1
  100. data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +2 -2
  101. data/lib/active_scaffold/bridges/file_column/list_ui.rb +4 -4
  102. data/lib/active_scaffold/bridges/paperclip.rb +1 -1
  103. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +1 -1
  104. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
  105. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +1 -1
  106. data/lib/active_scaffold/bridges/shared/date_bridge.rb +1 -1
  107. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +1 -1
  108. data/lib/active_scaffold/config/core.rb +9 -2
  109. data/lib/active_scaffold/config/list.rb +9 -13
  110. data/lib/active_scaffold/config/nested.rb +11 -2
  111. data/lib/active_scaffold/data_structures/action_columns.rb +19 -5
  112. data/lib/active_scaffold/data_structures/action_link.rb +9 -2
  113. data/lib/active_scaffold/data_structures/action_links.rb +5 -36
  114. data/lib/active_scaffold/data_structures/column.rb +21 -21
  115. data/lib/active_scaffold/data_structures/nested_info.rb +31 -44
  116. data/lib/active_scaffold/extensions/action_controller_rescueing.rb +1 -0
  117. data/lib/active_scaffold/extensions/action_view_rendering.rb +30 -36
  118. data/lib/active_scaffold/extensions/reverse_associations.rb +10 -6
  119. data/lib/active_scaffold/extensions/routing_mapper.rb +6 -5
  120. data/lib/active_scaffold/extensions/unsaved_associated.rb +1 -1
  121. data/lib/active_scaffold/finder.rb +18 -10
  122. data/lib/active_scaffold/helpers/association_helpers.rb +21 -2
  123. data/lib/active_scaffold/helpers/controller_helpers.rb +14 -16
  124. data/lib/active_scaffold/helpers/form_column_helpers.rb +161 -21
  125. data/lib/active_scaffold/helpers/id_helpers.rb +7 -7
  126. data/lib/active_scaffold/helpers/list_column_helpers.rb +42 -92
  127. data/lib/active_scaffold/helpers/search_column_helpers.rb +10 -3
  128. data/lib/active_scaffold/helpers/show_column_helpers.rb +4 -9
  129. data/lib/active_scaffold/helpers/view_helpers.rb +278 -78
  130. data/lib/active_scaffold/version.rb +2 -2
  131. data/lib/generators/active_scaffold_controller/templates/controller.rb +1 -1
  132. data/test/bridges/paperclip_test.rb +2 -2
  133. data/vendor/assets/javascripts/jquery-ui-timepicker-addon.js +1882 -1276
  134. metadata +79 -80
  135. data/README.md +0 -67
  136. data/frontends/default/views/_action_group.html.erb +0 -24
  137. data/frontends/default/views/_form_attribute.html.erb +0 -23
  138. data/frontends/default/views/_horizontal_subform.html.erb +0 -22
  139. data/frontends/default/views/_horizontal_subform_record.html.erb +0 -43
  140. data/frontends/default/views/_list.html.erb +0 -18
  141. data/frontends/default/views/_list_actions.html.erb +0 -15
  142. data/frontends/default/views/_list_header.html.erb +0 -10
  143. data/frontends/default/views/_list_record.html.erb +0 -13
  144. data/frontends/default/views/_list_record_columns.html.erb +0 -8
  145. data/frontends/default/views/_refresh_list.js.erb +0 -1
  146. data/frontends/default/views/_update_actions.html.erb +0 -9
  147. data/frontends/default/views/_vertical_subform.html.erb +0 -12
  148. data/frontends/default/views/_vertical_subform_record.html.erb +0 -43
  149. data/frontends/default/views/refresh_list.js.erb +0 -2
  150. data/frontends/default/views/update_column.js.erb +0 -15
  151. data/lib/active_scaffold/extensions/active_record_offset.rb +0 -12
  152. data/lib/active_scaffold/extensions/nil_id_in_url_params.rb +0 -7
@@ -13,6 +13,8 @@ module ActiveScaffold::DataStructures
13
13
  self.clear_link if value
14
14
  @inplace_edit = value
15
15
  end
16
+
17
+ attr_accessor :inplace_edit_update
16
18
 
17
19
  # Whether this column set is collapsed by default in contexts where collapsing is supported
18
20
  attr_accessor :collapsed
@@ -43,6 +45,12 @@ module ActiveScaffold::DataStructures
43
45
  end
44
46
  end
45
47
 
48
+ # A placeholder text, to be used inside blank text fields to describe, what should be typed in
49
+ attr_writer :placeholder
50
+ def placeholder
51
+ @placeholder || I18n.t(name, :scope => [:activerecord, :placeholder, active_record_class.to_s.underscore.to_sym], :default => '')
52
+ end
53
+
46
54
  # this will be /joined/ to the :name for the td's class attribute. useful if you want to style columns on different ActiveScaffolds the same way, but the columns have different names.
47
55
  attr_accessor :css_class
48
56
 
@@ -66,16 +74,6 @@ module ActiveScaffold::DataStructures
66
74
  cattr_accessor :send_form_on_update_column
67
75
  attr_accessor :send_form_on_update_column
68
76
 
69
- # column to be updated in a form when this column changes
70
- def update_column=(column_name)
71
- ActiveSupport::Deprecation.warn "Use update_columns= instead of update_column="
72
- self.update_columns = column_name
73
- end
74
-
75
- # send all the form instead of only new value when this column change
76
- cattr_accessor :send_form_on_update_column
77
- attr_accessor :send_form_on_update_column
78
-
79
77
  # sorting on a column can be configured four ways:
80
78
  # sort = true default, uses intelligent sorting sql default
81
79
  # sort = false sometimes sorting doesn't make sense
@@ -174,11 +172,7 @@ module ActiveScaffold::DataStructures
174
172
  end
175
173
 
176
174
  # a collection of columns to load when eager loading is disabled, if it's nil all columns will be loaded
177
- attr_accessor :select_associated_columns
178
- def select_columns=(value)
179
- ActiveSupport::Deprecation.warn "Use select_associated_columns= instead of select_columns="
180
- self.select_associated_columns = value
181
- end
175
+ attr_accessor :select_columns
182
176
 
183
177
  # describes how to search on a column
184
178
  # search = true default, uses intelligent search sql
@@ -304,6 +298,7 @@ module ActiveScaffold::DataStructures
304
298
  @options = {:format => :i18n_number} if self.number?
305
299
  @form_ui = :checkbox if @column and @column.type == :boolean
306
300
  @form_ui = :textarea if @column and @column.type == :text
301
+ @form_ui = :number if @column and self.number?
307
302
  @allow_add_existing = true
308
303
  @form_ui = self.class.association_form_ui if @association && self.class.association_form_ui
309
304
 
@@ -319,7 +314,6 @@ module ActiveScaffold::DataStructures
319
314
 
320
315
  @weight = estimate_weight
321
316
 
322
- self.clear_link if self.polymorphic_association?
323
317
  self.includes = (association and not polymorphic_association?) ? [association.name] : []
324
318
  end
325
319
 
@@ -354,6 +348,17 @@ module ActiveScaffold::DataStructures
354
348
  end
355
349
  end
356
350
 
351
+ # to cache method to get value in list
352
+ attr_accessor :list_method
353
+
354
+ # cache constraints for numeric columns (get in ActiveScaffold::Helpers::FormColumnHelpers::numerical_constraints_for_column)
355
+ attr_accessor :numerical_constraints
356
+
357
+ # the table.field name for this column, if applicable
358
+ def field
359
+ @field ||= [@active_record_class.quoted_table_name, field_name].join('.')
360
+ end
361
+
357
362
  protected
358
363
 
359
364
  def initialize_sort
@@ -381,11 +386,6 @@ module ActiveScaffold::DataStructures
381
386
 
382
387
  # the table name from the ActiveRecord class
383
388
  attr_reader :table
384
-
385
- # the table.field name for this column, if applicable
386
- def field
387
- @field ||= [@active_record_class.quoted_table_name, field_name].join('.')
388
- end
389
389
 
390
390
  def estimate_weight
391
391
  if singular_association?
@@ -3,32 +3,21 @@ module ActiveScaffold::DataStructures
3
3
  def self.get(model, params)
4
4
  nested_info = {}
5
5
  begin
6
- nested_info[:name] = (params[:association] || params[:named_scope]).to_sym
7
- nested_info[:parent_scaffold] = "#{params[:parent_scaffold].to_s.camelize}Controller".constantize
8
- nested_info[:parent_model] = nested_info[:parent_scaffold].active_scaffold_config.model
9
- nested_info[:parent_id] = if params[:association].nil?
10
- params[nested_info[:parent_model].name.foreign_key]
6
+ unless params[:association].nil?
7
+ ActiveScaffold::DataStructures::NestedInfoAssociation.new(model, params)
11
8
  else
12
- params[nested_info[:parent_model].reflect_on_association(params[:association].to_sym).active_record.name.foreign_key]
13
- end
14
- if nested_info[:parent_id]
15
- unless params[:association].nil?
16
- ActiveScaffold::DataStructures::NestedInfoAssociation.new(model, nested_info)
17
- else
18
- ActiveScaffold::DataStructures::NestedInfoScope.new(model, nested_info)
19
- end
9
+ ActiveScaffold::DataStructures::NestedInfoScope.new(model, params)
20
10
  end
21
11
  rescue ActiveScaffold::ControllerNotFound
22
12
  nil
23
13
  end
24
14
  end
25
15
 
26
- attr_accessor :association, :child_association, :parent_model, :parent_scaffold, :parent_id, :constrained_fields, :scope
16
+ attr_accessor :association, :child_association, :parent_model, :parent_scaffold, :parent_id, :param_name, :constrained_fields, :scope
27
17
 
28
- def initialize(model, nested_info)
29
- @parent_model = nested_info[:parent_model]
30
- @parent_id = nested_info[:parent_id]
31
- @parent_scaffold = nested_info[:parent_scaffold]
18
+ def initialize(model, params)
19
+ @parent_scaffold = "#{params[:parent_scaffold].to_s.camelize}Controller".constantize
20
+ @parent_model = @parent_scaffold.active_scaffold_config.model
32
21
  end
33
22
 
34
23
  def to_params
@@ -41,10 +30,6 @@ module ActiveScaffold::DataStructures
41
30
  result
42
31
  end
43
32
 
44
- def parent_scope
45
- @parent_scope ||= parent_model.find(parent_id)
46
- end
47
-
48
33
  def habtm?
49
34
  false
50
35
  end
@@ -69,6 +54,10 @@ module ActiveScaffold::DataStructures
69
54
  has_many? || habtm?
70
55
  end
71
56
 
57
+ def readonly_through_association?
58
+ false
59
+ end
60
+
72
61
  def through_association?
73
62
  false
74
63
  end
@@ -83,9 +72,11 @@ module ActiveScaffold::DataStructures
83
72
  end
84
73
 
85
74
  class NestedInfoAssociation < NestedInfo
86
- def initialize(model, nested_info)
87
- super(model, nested_info)
88
- @association = parent_model.reflect_on_association(nested_info[:name])
75
+ def initialize(model, params)
76
+ super
77
+ @association = parent_model.reflect_on_association(params[:association].to_sym)
78
+ @param_name = @association.active_record.name.foreign_key.to_sym
79
+ @parent_id = params[@param_name]
89
80
  iterate_model_associations(model)
90
81
  end
91
82
 
@@ -109,6 +100,12 @@ module ActiveScaffold::DataStructures
109
100
  association.macro == :has_one
110
101
  end
111
102
 
103
+ # A through association with has_one or has_many as source association
104
+ # create cannot be called in such through association
105
+ def readonly_through_association?
106
+ association.options[:through] && association.source_reflection.macro != :belongs_to
107
+ end
108
+
112
109
  def through_association?
113
110
  association.options[:through]
114
111
  end
@@ -132,31 +129,21 @@ module ActiveScaffold::DataStructures
132
129
  protected
133
130
 
134
131
  def iterate_model_associations(model)
135
- @constrained_fields = Set.new
132
+ @constrained_fields = []
136
133
  constrained_fields << association.foreign_key.to_sym unless association.belongs_to?
137
- model.reflect_on_all_associations.each do |current|
138
- if !current.belongs_to? && association != current && association.foreign_key.to_s == current.association_foreign_key.to_s
139
- constrained_fields << current.name.to_sym
140
- @child_association = current if current.klass == @parent_model
141
- end
142
- if association.foreign_key.to_s == current.foreign_key.to_s
143
- # show columns for has_many and has_one child associationes
144
- constrained_fields << current.name.to_sym if current.belongs_to?
145
- if association.options[:as] and current.options[:polymorphic]
146
- @child_association = current if association.options[:as].to_sym == current.name
147
- else
148
- @child_association = current if current.klass == @parent_model
149
- end
150
- end
134
+ if reverse = association.reverse(model)
135
+ @child_association = model.reflect_on_association(reverse)
136
+ constrained_fields << @child_association.name unless @child_association == association
151
137
  end
152
- @constrained_fields = @constrained_fields.to_a
153
138
  end
154
139
  end
155
140
 
156
141
  class NestedInfoScope < NestedInfo
157
- def initialize(model, nested_info)
158
- super(model, nested_info)
159
- @scope = nested_info[:name]
142
+ def initialize(model, params)
143
+ super
144
+ @scope = params[:named_scope].to_sym
145
+ @param_name = parent_model.name.foreign_key.to_sym
146
+ @parent_id = params[@param_name]
160
147
  @constrained_fields = []
161
148
  end
162
149
 
@@ -1,5 +1,6 @@
1
1
  module ActionController #:nodoc:
2
2
  class Base
3
+ # adding to ActionController::Base so it can overrided in ApplicationController
3
4
  def deny_access
4
5
  head :unauthorized
5
6
  end
@@ -1,20 +1,11 @@
1
1
  module ActionView
2
2
  class LookupContext
3
- module ViewPaths
4
- def find_all_templates(name, partial = false, locals = {})
5
- prefixes.collect do |prefix|
6
- view_paths.collect do |resolver|
7
- if Rails.version < '3.2.0' # FIXME: remove when rails 3.1 support is dropped
8
- temp_args = *args_for_lookup(name, [prefix], partial, locals)
9
- else
10
- temp_args = *args_for_lookup(name, [prefix], partial, locals, {})
11
- end
12
- temp_args[1] = temp_args[1][0]
13
- resolver.find_all(*temp_args)
14
- end
15
- end.flatten!
16
- end
3
+ attr_accessor :last_template
4
+
5
+ def find_template_with_last_template(name, prefixes = [], partial = false, keys = [], options = {})
6
+ self.last_template = find_template_without_last_template(name, prefixes, partial, keys, options)
17
7
  end
8
+ alias_method_chain :find_template, :last_template
18
9
  end
19
10
  end
20
11
 
@@ -44,21 +35,7 @@ module ActionView::Helpers #:nodoc:
44
35
  # Defining options[:label] lets you completely customize the list title for the embedded scaffold.
45
36
  #
46
37
  def render_with_active_scaffold(*args, &block)
47
- if args.first == :super
48
- last_view = view_stack.last || {:view => instance_variable_get(:@virtual_path).split('/').last}
49
- options = args[1] || {}
50
- options[:locals] ||= {}
51
- options[:locals].reverse_merge!(last_view[:locals] || {})
52
- if last_view[:templates].nil?
53
- last_view[:templates] = lookup_context.find_all_templates(last_view[:view], last_view[:partial], options[:locals].keys)
54
- last_view[:templates].shift
55
- end
56
- options[:template] = last_view[:templates].shift
57
- view_stack << last_view
58
- result = render_without_active_scaffold options
59
- view_stack.pop
60
- result
61
- elsif args.first.is_a? Hash and args.first[:active_scaffold]
38
+ if args.first.is_a? Hash and args.first[:active_scaffold]
62
39
  require 'digest/md5'
63
40
  options = args.first
64
41
 
@@ -87,21 +64,38 @@ module ActionView::Helpers #:nodoc:
87
64
  if ActiveScaffold.js_framework == :prototype
88
65
  javascript_tag("new Ajax.Updater('#{id}', '#{url}', {method: 'get', evalScripts: true});")
89
66
  elsif ActiveScaffold.js_framework == :jquery
90
- javascript_tag("jQuery('##{id}').load('#{url}');")
67
+ javascript_tag("jQuery('##{id}').load('#{url}', function() { $(this).trigger('as:element_updated'); });")
91
68
  end
92
69
  end
93
70
  end
94
71
 
72
+ elsif args.first == :super
73
+ prefix, template = @virtual_path.split('/')
74
+ options = args[1] || {}
75
+ options[:locals] ||= {}
76
+ options[:locals] = view_stack.last[:locals].merge!(options[:locals]) if view_stack.last && view_stack.last[:locals]
77
+ options[:template] = template
78
+ # if prefix is active_scaffold_overrides we must try to render with this prefix in following paths
79
+ if prefix != 'active_scaffold_overrides'
80
+ options[:prefixes] = lookup_context.prefixes.drop((lookup_context.prefixes.find_index(prefix) || -1) + 1)
81
+ else
82
+ options[:prefixes] = ['active_scaffold_overrides']
83
+ view_paths = lookup_context.view_paths
84
+ last_view_path = File.expand_path(File.dirname(File.dirname(lookup_context.last_template.inspect)), Rails.root)
85
+ lookup_context.view_paths = view_paths.drop(view_paths.find_index {|path| path.to_s == last_view_path} + 1)
86
+ end
87
+ result = render_without_active_scaffold options
88
+ lookup_context.view_paths = view_paths if view_paths
89
+ result
95
90
  else
96
- options = args.first
97
- if options.is_a?(Hash)
98
- current_view = {:view => options[:partial], :partial => true} if options[:partial]
99
- current_view = {:view => options[:template], :partial => false} if current_view.nil? && options[:template]
100
- current_view[:locals] = options[:locals] if !current_view.nil? && options[:locals]
101
- view_stack << current_view if current_view.present?
91
+ last_template = lookup_context.last_template
92
+ if args.first.is_a?(Hash)
93
+ current_view = {:locals => args.first[:locals]}
94
+ view_stack << current_view
102
95
  end
103
96
  result = render_without_active_scaffold(*args, &block)
104
97
  view_stack.pop if current_view.present?
98
+ lookup_context.last_template = last_template
105
99
  result
106
100
  end
107
101
  end
@@ -7,19 +7,23 @@ module ActiveRecord
7
7
  end
8
8
 
9
9
  attr_writer :reverse
10
- def reverse
11
- @reverse ||= inverse_of.try(:name)
10
+ def reverse(klass = nil)
11
+ unless defined? @reverse
12
+ @reverse ||= inverse_of.try(:name)
13
+ end
14
+ @reverse || (autodetect_inverse(klass).try(:name) unless klass.nil?)
12
15
  end
13
16
 
14
17
  def inverse_of_with_autodetect
15
18
  inverse_of_without_autodetect || autodetect_inverse
16
19
  end
17
20
  alias_method_chain :inverse_of, :autodetect
18
-
21
+
19
22
  protected
20
23
 
21
- def autodetect_inverse
22
- return nil if options[:polymorphic]
24
+ def autodetect_inverse(klass = nil)
25
+ return nil if klass.nil? && options[:polymorphic]
26
+ klass ||= self.klass
23
27
  reverse_matches = []
24
28
 
25
29
  # stage 1 filter: collect associations that point back to this model and use the same foreign_key
@@ -31,7 +35,7 @@ module ActiveRecord
31
35
  else
32
36
  # skip over has_many :through associations
33
37
  next if assoc.options[:through]
34
- next unless assoc.options[:polymorphic] or assoc.class_name.constantize == self.active_record
38
+ next unless assoc.options[:polymorphic] or assoc.class_name == self.active_record.name
35
39
 
36
40
  case [assoc.macro, self.macro].find_all{|m| m == :has_and_belongs_to_many}.length
37
41
  # if both are a habtm, then match them based on the join table
@@ -1,21 +1,22 @@
1
1
  module ActionDispatch
2
2
  module Routing
3
3
  ACTIVE_SCAFFOLD_CORE_ROUTING = {
4
- :collection => {:show_search => :get, :render_field => :get, :mark => :post},
5
- :member => {:row => :get, :update_column => :post, :render_field => :get, :mark => :post}
4
+ :collection => {:show_search => :get, :render_field => :post, :mark => :post},
5
+ :member => {:row => :get, :update_column => :post, :render_field => [:get, :post], :mark => :post}
6
6
  }
7
7
  ACTIVE_SCAFFOLD_ASSOCIATION_ROUTING = {
8
8
  :collection => {:edit_associated => :get, :new_existing => :get, :add_existing => :post},
9
- :member => {:edit_associated => :get, :add_association => :get, :destroy_existing => :delete}
9
+ :member => {:edit_associated => :get, :destroy_existing => :delete}
10
10
  }
11
11
  class Mapper
12
12
  module Base
13
13
  def as_routes(options = {:association => true})
14
14
  collection do
15
- ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection].each {|name, type| send(type, name)}
15
+ ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:collection].each {|name, type| match(name, :via => type)}
16
16
  end
17
17
  member do
18
- ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:member].each {|name, type| send(type, name)}
18
+ ActionDispatch::Routing::ACTIVE_SCAFFOLD_CORE_ROUTING[:member].each {|name, type| match(name, :via => type)}
19
+ get 'list', :action => :index
19
20
  end
20
21
  as_association_routes if options[:association]
21
22
  end
@@ -4,7 +4,7 @@ class ActiveRecord::Base
4
4
  return true if path.include?(self) # prevent recursion (if associated and parent are new records)
5
5
  path << self
6
6
  # using [].all? syntax to avoid a short-circuit
7
- with_unsaved_associated { |a| [a.valid?, a.associated_valid?(path)].all? {|v| v == true} }
7
+ with_unsaved_associated { |a| [a.valid?, a.associated_valid?(path)].all? }
8
8
  end
9
9
 
10
10
  def save_associated
@@ -148,7 +148,7 @@ module ActiveScaffold
148
148
 
149
149
  def condition_value_for_numeric(column, value)
150
150
  return value if value.nil?
151
- value = i18n_number_to_native_format(value) if [:i18n_number, :currency].include?(column.options[:format])
151
+ value = i18n_number_to_native_format(value) if [:i18n_number, :currency].include?(column.options[:format]) && column.search_ui != :number
152
152
  case (column.search_ui || column.column.type)
153
153
  when :integer then value.to_i rescue value ? 1 : 0
154
154
  when :float then value.to_f
@@ -275,12 +275,14 @@ module ActiveScaffold
275
275
  ]
276
276
  end
277
277
 
278
- # returns a single record (the given id) but only if it's allowed for the specified action.
278
+ # returns a single record (the given id) but only if it's allowed for the specified security options.
279
+ # security options can be a hash for authorized_for? method or a value to check as a :crud_type
279
280
  # accomplishes this by checking model.#{action}_authorized?
280
281
  # TODO: this should reside on the model, not the controller
281
- def find_if_allowed(id, crud_type, klass = beginning_of_chain)
282
+ def find_if_allowed(id, security_options, klass = beginning_of_chain)
282
283
  record = klass.find(id)
283
- raise ActiveScaffold::RecordNotAllowed, "#{klass} with id = #{id}" unless record.authorized_for?(:crud_type => crud_type.to_sym)
284
+ security_options = {:crud_type => security_options.to_sym} unless security_options.is_a? Hash
285
+ raise ActiveScaffold::RecordNotAllowed, "#{klass} with id = #{id}" unless record.authorized_for? security_options
284
286
  return record
285
287
  end
286
288
  # valid options may include:
@@ -341,7 +343,7 @@ module ActiveScaffold
341
343
  else
342
344
  pager = ::Paginator.new(count, options[:per_page]) do |offset, per_page|
343
345
  find_options.merge!(:offset => offset, :limit => per_page) if options[:pagination]
344
- append_to_query(klass, find_options).all
346
+ append_to_query(klass, find_options)
345
347
  end
346
348
  end
347
349
  pager.page(options[:page])
@@ -351,14 +353,20 @@ module ActiveScaffold
351
353
  conditions = all_conditions
352
354
  includes = active_scaffold_config.list.count_includes
353
355
  includes ||= active_scaffold_includes unless conditions.nil?
354
- append_to_query(beginning_of_chain, :conditions => conditions, :includes => includes,
355
- :joins => joins_for_collection).calculate(column.calculate, column.name)
356
+ primary_key = active_scaffold_config.model.primary_key
357
+ subquery = append_to_query(beginning_of_chain, :conditions => conditions, :joins => joins_for_collection)
358
+ subquery = subquery.select(active_scaffold_config.columns[primary_key].field)
359
+ if includes
360
+ includes_relation = beginning_of_chain.includes(includes)
361
+ subquery = subquery.send(:apply_join_dependency, subquery, includes_relation.send(:construct_join_dependency_for_association_find))
362
+ end
363
+ beginning_of_chain.where(primary_key => subquery).calculate(column.calculate, column.name)
356
364
  end
357
365
 
358
366
  def append_to_query(query, options)
359
367
  options.assert_valid_keys :where, :select, :group, :reorder, :limit, :offset, :joins, :includes, :lock, :readonly, :from, :conditions
360
- query = apply_conditions(query, *options[:conditions]) if options[:conditions]
361
- options.reject{|k, v| k == :conditions || v.blank?}.inject(query) do |query, (k, v)|
368
+ query = apply_conditions(query, *options.delete(:conditions)) if options[:conditions]
369
+ options.reject{|k, v| v.blank?}.inject(query) do |query, (k, v)|
362
370
  query.send((k.to_sym), v)
363
371
  end
364
372
  end
@@ -388,7 +396,7 @@ module ActiveScaffold
388
396
  def sort_collection_by_column(collection, column, order)
389
397
  sorter = column.sort[:method]
390
398
  collection = collection.sort_by { |record|
391
- value = (sorter.is_a? Proc) ? record.instance_eval(&sorter) : record.instance_eval(sorter)
399
+ value = (sorter.is_a? Proc) ? record.instance_eval(&sorter) : record.instance_eval(sorter.to_s)
392
400
  value = '' if value.nil?
393
401
  value
394
402
  }