active_scaffold 3.2.20 → 3.3.0.rc

Sign up to get free protection for your applications and to get access to all the features.
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
  }