active_scaffold 3.2.12 → 3.2.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/CHANGELOG +14 -1
  2. data/app/assets/javascripts/jquery/active_scaffold.js +8 -6
  3. data/app/assets/javascripts/prototype/active_scaffold.js +4 -3
  4. data/config/locales/de.yml +1 -1
  5. data/config/locales/en.yml +1 -1
  6. data/config/locales/es.yml +1 -1
  7. data/config/locales/fr.yml +1 -1
  8. data/config/locales/hu.yml +1 -1
  9. data/config/locales/ja.yml +1 -1
  10. data/config/locales/ru.yml +6 -4
  11. data/frontends/default/views/_base_form.html.erb +1 -1
  12. data/frontends/default/views/_form_hidden_attribute.html.erb +6 -1
  13. data/frontends/default/views/_horizontal_subform_header.html.erb +1 -1
  14. data/frontends/default/views/_horizontal_subform_record.html.erb +1 -1
  15. data/frontends/default/views/_list_inline_adapter.html.erb +1 -1
  16. data/frontends/default/views/_render_field.js.erb +1 -1
  17. data/frontends/default/views/_show.html.erb +1 -1
  18. data/frontends/default/views/_update_actions.html.erb +1 -1
  19. data/frontends/default/views/_vertical_subform_record.html.erb +1 -1
  20. data/lib/active_scaffold.rb +3 -3
  21. data/lib/active_scaffold/actions/core.rb +5 -11
  22. data/lib/active_scaffold/actions/delete.rb +0 -1
  23. data/lib/active_scaffold/actions/mark.rb +9 -4
  24. data/lib/active_scaffold/bridges/date_picker.rb +1 -1
  25. data/lib/active_scaffold/bridges/date_picker/ext.rb +7 -0
  26. data/lib/active_scaffold/bridges/date_picker/helper.rb +1 -1
  27. data/lib/active_scaffold/bridges/shared/date_bridge.rb +3 -3
  28. data/lib/active_scaffold/config/nested.rb +1 -1
  29. data/lib/active_scaffold/config/show.rb +1 -1
  30. data/lib/active_scaffold/config/update.rb +1 -1
  31. data/lib/active_scaffold/data_structures/action_link.rb +6 -0
  32. data/lib/active_scaffold/data_structures/action_links.rb +7 -2
  33. data/lib/active_scaffold/data_structures/column.rb +8 -8
  34. data/lib/active_scaffold/data_structures/nested_info.rb +5 -1
  35. data/lib/active_scaffold/extensions/action_controller_rendering.rb +0 -2
  36. data/lib/active_scaffold/extensions/action_controller_rescueing.rb +7 -0
  37. data/lib/active_scaffold/finder.rb +58 -40
  38. data/lib/active_scaffold/helpers/form_column_helpers.rb +4 -1
  39. data/lib/active_scaffold/helpers/search_column_helpers.rb +4 -2
  40. data/lib/active_scaffold/helpers/view_helpers.rb +4 -1
  41. data/lib/active_scaffold/tableless.rb +0 -1
  42. data/lib/active_scaffold/version.rb +1 -1
  43. data/lib/generators/active_scaffold/active_scaffold_generator.rb +1 -0
  44. metadata +10 -9
data/CHANGELOG CHANGED
@@ -1,4 +1,17 @@
1
- = 3.2.12 (not released yet)
1
+ = 3.2.13 (not released yet)
2
+ - Fix destroy action, was broken in 3.2.12
3
+ - Remove default :method sorting for associations, it wasn't useful and can be slow
4
+ - Rescue from ActiveScaffold::ActionNotAllowed and ActiveScaffold::RecordNotAllowed with 401 response, it can be overrided with deny_access method in ApplicationController.
5
+ - Allow to set arrays in search_sql so one column can search in multiple db columns, resulting sql chunks will be OR'ed
6
+ - Hide text input on searching for null or not null
7
+ - Add some classes to forms to improve CSS customization
8
+ - Fix nested links for STI controllers with common configuration in a base controller
9
+ - Fix adding routes twice in active_scaffold generator
10
+ - Restore old behavior for action_link's security_method, ignore_method already hides the link
11
+ - Add data-cancel-refresh to action links, so nested scaffold's behaviour can be applied to other action links and when adapter is closed row will be refreshed.
12
+ - fix support for tableless models in rails >= 3.2.5
13
+
14
+ = 3.2.12
2
15
  - improve support for tableless models, add support for count
3
16
  - fix div id for nested scaffolds
4
17
  - add config.timestamped_messages and config.highlight_messages
@@ -72,8 +72,8 @@ jQuery(document).ready(function() {
72
72
 
73
73
  if (action_link) {
74
74
  var cancel_url = as_cancel.attr('href');
75
- var refresh_data = as_cancel.attr('data-refresh');
76
- if (refresh_data !== 'true' || !cancel_url) {
75
+ var refresh_data = action_link.tag.data('cancel-refresh');
76
+ if (!refresh_data || !cancel_url) {
77
77
  action_link.close();
78
78
  return false;
79
79
  }
@@ -166,11 +166,13 @@ jQuery(document).ready(function() {
166
166
  });
167
167
 
168
168
  jQuery('select.as_search_range_option').live('change', function(event) {
169
- ActiveScaffold[jQuery(this).val() == 'BETWEEN' ? 'show' : 'hide'](jQuery(this).parent().find('.as_search_range_between'));
169
+ var element = jQuery(this);
170
+ ActiveScaffold[element.val() == 'BETWEEN' ? 'show' : 'hide'](element.closest('dd').find('.as_search_range_between'));
171
+ ActiveScaffold[(element.val() == 'null' || element.val() == 'not_null') ? 'hide' : 'show'](element.attr('id').replace(/_opt/, '_numeric'));
170
172
  return true;
171
173
  });
172
174
 
173
- jQuery('select.as_search_range_option').live('change', function(event) {
175
+ jQuery('select.as_search_date_time_option').live('change', function(event) {
174
176
  var element = jQuery(this);
175
177
  ActiveScaffold[!(element.val() == 'PAST' || element.val() == 'FUTURE' || element.val() == 'RANGE') ? 'show' : 'hide'](element.attr('id').replace(/_opt/, '_numeric'));
176
178
  ActiveScaffold[(element.val() == 'PAST' || element.val() == 'FUTURE') ? 'show' : 'hide'](element.attr('id').replace(/_opt/, '_trend'));
@@ -440,7 +442,7 @@ var ActiveScaffold = {
440
442
  update_inplace_edit: function(element, value, empty) {
441
443
  if (typeof(element) == 'string') element = '#' + element;
442
444
  this.replace_html(jQuery(element), value);
443
- if (empty) jQuery(element).closest('td').addClass('empty');
445
+ jQuery(element).closest('td')[empty ? 'addClass' : 'removeClass']('empty');
444
446
  },
445
447
 
446
448
  hide: function(element) {
@@ -971,7 +973,7 @@ ActiveScaffold.ActionLink.Abstract = Class.extend({
971
973
  this.adapter = element;
972
974
  this.adapter.addClass('as_adapter');
973
975
  this.adapter.data('action_link', this);
974
- if (this.refresh_url) jQuery('.as_cancel[data-refresh=true]', this.adapter).attr('href', this.refresh_url);
976
+ if (this.refresh_url) jQuery('.as_cancel', this.adapter).attr('href', this.refresh_url);
975
977
  }
976
978
  });
977
979
 
@@ -95,10 +95,10 @@ document.observe("dom:loaded", function() {
95
95
  var action_link = ActiveScaffold.find_action_link(as_cancel);
96
96
 
97
97
  if (action_link) {
98
- var refresh_data = as_cancel.readAttribute('data-refresh');
99
- if (refresh_data === 'true' && action_link.refresh_url) {
98
+ var refresh_data = action_link.readAttribute('data-cancel-refresh');
99
+ if (refresh_data && action_link.refresh_url) {
100
100
  event.memo.url = action_link.refresh_url;
101
- } else if (refresh_data === 'false' || as_cancel.readAttribute('href').blank()) {
101
+ } else if (!refresh_data || as_cancel.readAttribute('href').blank()) {
102
102
  action_link.close();
103
103
  event.stop();
104
104
  }
@@ -252,6 +252,7 @@ document.observe("dom:loaded", function() {
252
252
  document.on('change', 'select.as_search_range_option', function(event) {
253
253
  var element = event.findElement();
254
254
  Element[element.value == 'BETWEEN' ? 'show' : 'hide'](element.readAttribute('id').sub('_opt', '_between'));
255
+ Element[(element.value == 'null' || element.value == 'not_null') ? 'hide' : 'show'](element.readAttribute('id').sub('_opt', '_numeric'));
255
256
  return true;
256
257
  });
257
258
  document.on('change', 'select.as_search_date_time_option', function(event) {
@@ -96,7 +96,7 @@ de:
96
96
  months: 'Monate'
97
97
  years: 'Jahre'
98
98
  optional_attributes: 'Weitere'
99
- null: 'Null'
99
+ :null: 'Null'
100
100
  not_null: 'Nicht Null'
101
101
  date_picker_options:
102
102
  weekHeader: 'Wo'
@@ -96,7 +96,7 @@ en:
96
96
  months: 'Months'
97
97
  years: 'Years'
98
98
  optional_attributes: 'Further Options'
99
- null: 'Null'
99
+ :null: 'Null'
100
100
  not_null: 'Not Null'
101
101
  date_picker_options:
102
102
  weekHeader: 'Wk'
@@ -98,7 +98,7 @@ es:
98
98
  months: 'Meses'
99
99
  years: 'Años'
100
100
  optional_attributes: 'Más opciones'
101
- null: 'Nulo'
101
+ :null: 'Nulo'
102
102
  not_null: 'No Nulo'
103
103
  date_picker_options:
104
104
  weekHeader: 'Sm'
@@ -96,7 +96,7 @@ fr:
96
96
  months: 'Mois'
97
97
  years: 'Années'
98
98
  optional_attributes: 'Options additionnelles'
99
- null: 'Nulle'
99
+ :null: 'Nulle'
100
100
  not_null: 'Non Nulle'
101
101
  date_picker_options:
102
102
  weekHeader: 'Sm'
@@ -96,7 +96,7 @@ hu:
96
96
  months: 'Months'
97
97
  years: 'Years'
98
98
  optional_attributes: 'Further Options'
99
- null: 'Null'
99
+ :null: 'Null'
100
100
  not_null: 'Not Null'
101
101
  date_picker_options:
102
102
  weekHeader: 'Wk'
@@ -96,7 +96,7 @@ ja:
96
96
  months: 'Months'
97
97
  years: 'Years'
98
98
  optional_attributes: 'Further Options'
99
- null: 'Null'
99
+ :null: 'Null'
100
100
  not_null: 'Not Null'
101
101
  date_picker_options:
102
102
  weekHeader: 'Wk'
@@ -38,7 +38,7 @@ ru:
38
38
  inplace_edit_handle: '--'
39
39
  live_search: 'Поиск'
40
40
  loading: 'Загрузка…'
41
- mark_all_records: "Mark all"
41
+ mark_all_records: "Отметить все"
42
42
  next: 'Следующее'
43
43
  no_entries: 'Нет записей'
44
44
  no_options: 'Нет вариантов'
@@ -48,8 +48,10 @@ ru:
48
48
  previous: 'Предыдущее'
49
49
  print: 'Печать'
50
50
  records_marked:
51
- one: "1 marked %{model}"
52
- other: "%{count} marked %{model}"
51
+ one: "Отмечена 1 запись"
52
+ few: "Отмечено %{count} записи"
53
+ many: "Отмечено %{count} записей"
54
+ other: "Отмечено %{count} записи"
53
55
  refresh: 'Обновить'
54
56
  remove: 'Удалить'
55
57
  remove_file: 'Удалить или заменить файл'
@@ -100,7 +102,7 @@ ru:
100
102
  months: 'месяцев'
101
103
  years: 'лет'
102
104
  optional_attributes: 'Дополнительные настройки'
103
- null: 'Пусто'
105
+ :null: 'Пусто'
104
106
  not_null: 'Не пусто'
105
107
  date_picker_options:
106
108
  weekHeader: 'Нед.'
@@ -20,7 +20,7 @@ options = {:onsubmit => onsubmit,
20
20
  :class => "as_form #{form_action.to_s}",
21
21
  :method => method,
22
22
  'data-loading' => true}
23
- cancel_options = {:class => 'as_cancel', 'data-refresh' => false}
23
+ cancel_options = {:class => 'as_cancel'}
24
24
 
25
25
  cancel_options[:remote] = true if xhr #cancel link does nt have to care about multipart forms
26
26
  if xhr && multipart # file_uploads
@@ -1,2 +1,7 @@
1
1
  <% scope ||= nil %>
2
- <%= hidden_field :record, column.name, active_scaffold_input_options(column, scope) %>
2
+ <dl style="display: none;">
3
+ <dt></dt>
4
+ <dd>
5
+ <%= hidden_field :record, column.name, active_scaffold_input_options(column, scope) %>
6
+ </dd>
7
+ </dl>
@@ -5,7 +5,7 @@
5
5
  hidden = column_renders_as(column) == :hidden
6
6
  next unless in_subform?(column, parent_record)
7
7
  -%>
8
- <th class="<%= "#{'required' if column.required?} #{'hidden' if hidden}" %>"><label><%= column.label unless hidden %></label></th>
8
+ <th class="<%= "#{column.name}-column #{'required' if column.required?} #{'hidden' if hidden}" %>"><label><%= column.label unless hidden %></label></th>
9
9
  <% end -%>
10
10
  </tr>
11
11
  </thead>
@@ -24,7 +24,7 @@
24
24
  <% unless readonly and not @record.new_record? or not @record.authorized_for?(:crud_type => crud_type, :column => column.name) -%>
25
25
  <%= render :partial => form_partial_for_column(column), :locals => { :column => column, :scope => scope } -%>
26
26
  <% else -%>
27
- <p class="<%= column.name %>-input"><%= get_column_value(@record, column) -%></p>
27
+ <%= content_tag :span, get_column_value(@record, column), active_scaffold_input_options(column, scope).except(:name) -%>
28
28
  <% end -%>
29
29
  </td>
30
30
  <% end -%>
@@ -12,7 +12,7 @@
12
12
  <tr class="inline-adapter" id="<%= element_row_id :action => :nested %>">
13
13
  <td colspan="<%= column_count %>" class="inline-adapter-cell">
14
14
  <div class="<%= "#{params[:action]}-view" if params[:action] %> <%= "#{nested? ? nested.name : id_from_controller(params[:controller])}-view" %> view">
15
- <%= link_to(as_(:close), '', :class => 'inline-adapter-close as_cancel', :remote => true, :title => as_(:close), 'data-refresh' => (action_name == 'index' ? true : false)) -%>
15
+ <%= link_to(as_(:close), '', :class => 'inline-adapter-close as_cancel', :remote => true, :title => as_(:close)) -%>
16
16
  <%= payload -%>
17
17
  </div>
18
18
  </td>
@@ -2,7 +2,7 @@
2
2
  column = if render_field.is_a? ActiveScaffold::DataStructures::Column
3
3
  render_field
4
4
  else
5
- active_scaffold_config.columns[render_field.to_sym] unless render_field.is_a? ActiveScaffold::DataStructures::Column
5
+ active_scaffold_config.columns[render_field.to_sym]
6
6
  end
7
7
  @rendered ||= Set.new
8
8
  return if @rendered.include? column.name
@@ -3,6 +3,6 @@
3
3
  <%= render :partial => 'show_columns', :locals => {:columns => active_scaffold_config.show.columns} -%>
4
4
 
5
5
  <p class="form-footer">
6
- <%= link_to as_(:close), main_path_to_return, :class => 'as_cancel', :remote => request.xhr?, 'data-refresh' => false %>
6
+ <%= link_to as_(:close), main_path_to_return, :class => 'as_cancel', :remote => request.xhr? %>
7
7
  <%= loading_indicator_tag(:action => :create, :id => params[:id]) %>
8
8
  </p>
@@ -1,7 +1,7 @@
1
1
  <div class="active-scaffold-header">
2
2
  <div class="actions">
3
3
  <% active_scaffold_config.action_links.member.each do |link| -%>
4
- <% next unless link.action == 'nested' -%>
4
+ <% next unless link.action == 'index' -%>
5
5
  <% next if skip_action_link(link) -%>
6
6
  <%= record.authorized_for?(:crud_type => link.crud_type, :action => link.action) ? render_action_link(link, url_options, record) : "<a class='disabled'>#{link.label}</a>" -%>
7
7
  <% end -%>
@@ -24,7 +24,7 @@
24
24
  <% unless readonly and not @record.new_record? or not @record.authorized_for?(:crud_type => crud_type, :column => column.name) -%>
25
25
  <%= render :partial => form_partial_for_column(column), :locals => { :column => column, :scope => scope } -%>
26
26
  <% else -%>
27
- <p class="<%= column.name %>-input"><%= get_column_value(@record, column) -%></p>
27
+ <%= content_tag :span, get_column_value(@record, column), active_scaffold_input_options(column, scope).except(:name) -%>
28
28
  <% end -%>
29
29
  </li>
30
30
  <% end -%>
@@ -266,11 +266,11 @@ module ActiveScaffold
266
266
  unless controller.nil?
267
267
  options.reverse_merge! :label => column.label, :position => :after, :type => :member, :controller => (controller == :polymorph ? controller : controller.controller_path), :column => column
268
268
  options[:parameters] ||= {}
269
- options[:parameters].reverse_merge! :parent_scaffold => controller_path, :association => column.association.name
269
+ options[:parameters].reverse_merge! :association => column.association.name
270
270
  if column.plural_association?
271
271
  # note: we can't create nested scaffolds on :through associations because there's no reverse association.
272
272
 
273
- ActiveScaffold::DataStructures::ActionLink.new('index', options) #unless column.through_association?
273
+ ActiveScaffold::DataStructures::ActionLink.new('index', options.merge(:refresh_on_close => true)) #unless column.through_association?
274
274
  else
275
275
  actions = controller.active_scaffold_config.actions unless controller == :polymorph
276
276
  actions ||= [:create, :update, :show]
@@ -285,7 +285,7 @@ module ActiveScaffold
285
285
  def link_for_association_as_scope(scope, options = {})
286
286
  options.reverse_merge! :label => scope, :position => :after, :type => :member, :controller => controller_path
287
287
  options[:parameters] ||= {}
288
- options[:parameters].reverse_merge! :parent_scaffold => controller_path, :named_scope => scope
288
+ options[:parameters].reverse_merge! :named_scope => scope
289
289
  ActiveScaffold::DataStructures::ActionLink.new('index', options)
290
290
  end
291
291
 
@@ -4,6 +4,7 @@ module ActiveScaffold::Actions
4
4
  base.class_eval do
5
5
  before_filter :register_constraints_with_action_columns, :if => :embedded?
6
6
  after_filter :clear_flashes
7
+ rescue_from ActiveScaffold::RecordNotAllowed, ActiveScaffold::ActionNotAllowed, :with => :deny_access
7
8
  end
8
9
  base.helper_method :nested?
9
10
  base.helper_method :calculate
@@ -75,6 +76,10 @@ module ActiveScaffold::Actions
75
76
  end
76
77
  end
77
78
 
79
+ def each_marked_record(&block)
80
+ active_scaffold_config.model.find(marked_records.to_a).each &block
81
+ end
82
+
78
83
  def marked_records
79
84
  active_scaffold_session_storage[:marked_records] ||= Set.new
80
85
  end
@@ -193,16 +198,5 @@ module ActiveScaffold::Actions
193
198
  (default_formats + active_scaffold_config.formats).uniq
194
199
  end
195
200
  end
196
-
197
- def response_code_for_rescue(exception)
198
- case exception
199
- when ActiveScaffold::RecordNotAllowed
200
- "403 Record Not Allowed"
201
- when ActiveScaffold::ActionNotAllowed
202
- "403 Action Not Allowed"
203
- else
204
- super
205
- end
206
- end
207
201
  end
208
202
  end
@@ -49,7 +49,6 @@ module ActiveScaffold::Actions
49
49
  @record ||= destroy_find_record
50
50
  begin
51
51
  self.successful = @record.destroy
52
- @record.as_marked = false if successful?
53
52
  rescue Exception => ex
54
53
  flash[:warning] = as_(:cant_destroy_record, :record => @record.to_label)
55
54
  self.successful = false
@@ -56,9 +56,9 @@ module ActiveScaffold::Actions
56
56
  if params[:id]
57
57
  find_if_allowed(params[:id], :read).as_marked = true
58
58
  elsif active_scaffold_config.mark.mark_all_mode == :page && !mark_all_scope_forced?
59
- each_record_in_page {|record| marked_records << record.id}
59
+ each_record_in_page { |record| record.as_marked = true }
60
60
  else
61
- each_record_in_scope {|record| marked_records << record.id}
61
+ each_record_in_scope { |record| record.as_marked = true }
62
62
  end
63
63
  end
64
64
 
@@ -66,12 +66,17 @@ module ActiveScaffold::Actions
66
66
  if params[:id]
67
67
  find_if_allowed(params[:id], :read).as_marked = false
68
68
  elsif active_scaffold_config.mark.mark_all_mode == :page
69
- each_record_in_page {|record| marked_records.delete(record.id)}
69
+ each_record_in_page { |record| record.as_marked = false }
70
70
  else
71
- each_record_in_scope {|record| marked_records.delete(record.id)}
71
+ each_record_in_scope { |record| record.as_marked = false }
72
72
  end
73
73
  end
74
74
 
75
+ def do_destroy
76
+ super
77
+ @record.as_marked = false if successful?
78
+ end
79
+
75
80
  # The default security delegates to ActiveRecordPermissions.
76
81
  # You may override the method to customize.
77
82
  def mark_authorized?
@@ -8,7 +8,7 @@ module ActiveScaffold::Bridges
8
8
  ActiveScaffold.js_framework == :jquery
9
9
  end
10
10
  def self.localization
11
- "jQuery(function($){
11
+ "jQuery(function($){
12
12
  if (typeof($.datepicker) === 'object') {
13
13
  #{Helper.date_options_for_locales}
14
14
  $.datepicker.setDefaults($.datepicker.regional['#{::I18n.locale}']);
@@ -49,6 +49,13 @@ ActionView::Base.class_eval do
49
49
  end
50
50
  ActiveScaffold::Finder::ClassMethods.module_eval do
51
51
  include ActiveScaffold::Bridges::Shared::DateBridge::Finder::ClassMethods
52
+ def datetime_conversion_for_condition(column)
53
+ if column.search_ui == :date_picker
54
+ :to_date
55
+ else
56
+ super
57
+ end
58
+ end
52
59
  alias_method :condition_for_date_picker_type, :condition_for_date_bridge_type
53
60
  alias_method :condition_for_datetime_picker_type, :condition_for_date_picker_type
54
61
  end
@@ -158,7 +158,7 @@ module ActiveScaffold::Bridges
158
158
  options = active_scaffold_input_text_options(options.merge(column.options))
159
159
  options[:class] << " #{column.search_ui.to_s}"
160
160
  options[:style] = (options[:show].nil? || options[:show]) ? nil : "display: none"
161
- format = options.delete(:format) || column.form_ui == :date_picker ? :default : :picker
161
+ format = options.delete(:format) || column.search_ui == :date_picker ? :default : :picker
162
162
  datepicker_format_options(column, format, options)
163
163
  text_field_tag("#{options[:name]}[#{name}]", value ? l(value, :format => format) : nil, options.merge(:id => "#{options[:id]}_#{name}", :name => "#{options[:name]}[#{name}]"))
164
164
  end
@@ -112,15 +112,15 @@ module ActiveScaffold
112
112
  column.search_sql.call(from_value, to_value, operator)
113
113
  else
114
114
  unless operator.nil?
115
- ["#{column.search_sql} #{value[:opt]} ?", from_value.to_s(:db)] unless from_value.nil?
115
+ ["%{search_sql} #{value[:opt]} ?", from_value.to_s(:db)] unless from_value.nil?
116
116
  else
117
- ["#{column.search_sql} BETWEEN ? AND ?", from_value.to_s(:db), to_value.to_s(:db)] unless from_value.nil? && to_value.nil?
117
+ ["%{search_sql} BETWEEN ? AND ?", from_value.to_s(:db), to_value.to_s(:db)] unless from_value.nil? && to_value.nil?
118
118
  end
119
119
  end
120
120
  end
121
121
 
122
122
  def date_bridge_from_to(column, value)
123
- conversion = column.column.type == :date ? :to_date : :to_time
123
+ conversion = datetime_conversion_for_condition(column)
124
124
  case value[:opt]
125
125
  when 'RANGE'
126
126
  date_bridge_from_to_for_range(column, value).collect(&conversion)
@@ -21,7 +21,7 @@ module ActiveScaffold::Config
21
21
  def add_link(attribute, options = {})
22
22
  column = @core.columns[attribute.to_sym]
23
23
  unless column.nil? || column.association.nil?
24
- options.reverse_merge! :security_method => :nested_authorized?, :label => column.association.klass.model_name.human({:count => 2, :default => column.association.klass.name.pluralize})
24
+ options.reverse_merge! :security_method => :nested_authorized?, :label => column.association.klass.model_name.human({:count => 2, :default => column.association.klass.name.pluralize})
25
25
  action_link = @core.link_for_association(column, options)
26
26
  action_link.action ||= :index
27
27
  @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
@@ -11,7 +11,7 @@ module ActiveScaffold::Config
11
11
  # global level configuration
12
12
  # --------------------------
13
13
  cattr_accessor :link
14
- @@link = ActiveScaffold::DataStructures::ActionLink.new('show', :label => :show, :type => :member, :security_method => :show_authorized?)
14
+ @@link = ActiveScaffold::DataStructures::ActionLink.new('show', :label => :show, :type => :member, :security_method => :show_authorized?, :ignore_method => :show_ignore?)
15
15
  # instance-level configuration
16
16
  # ----------------------------
17
17
 
@@ -15,7 +15,7 @@ module ActiveScaffold::Config
15
15
  def self.link=(val)
16
16
  @@link = val
17
17
  end
18
- @@link = ActiveScaffold::DataStructures::ActionLink.new('edit', :label => :edit, :type => :member, :security_method => :update_authorized?)
18
+ @@link = ActiveScaffold::DataStructures::ActionLink.new('edit', :label => :edit, :type => :member, :security_method => :update_authorized?, :ignore_method => :update_ignore?)
19
19
 
20
20
  # instance-level configuration
21
21
  # ----------------------------
@@ -82,6 +82,7 @@ module ActiveScaffold::DataStructures
82
82
  end
83
83
 
84
84
  # what method to call on the controller to see if this action_link should be visible
85
+ # if method return false, link will be disabled
85
86
  # note that this is only the UI part of the security. to prevent URL hax0rz, you also need security on requests (e.g. don't execute update method unless authorized).
86
87
  attr_writer :security_method
87
88
  def security_method
@@ -91,7 +92,12 @@ module ActiveScaffold::DataStructures
91
92
  def security_method_set?
92
93
  !!@security_method
93
94
  end
95
+
96
+ # enable it to refresh the parent row when the view is closed
97
+ attr_accessor :refresh_on_close
94
98
 
99
+ # what method to call on the controller to see if this action_link should be visible
100
+ # if method return true, link won't be displayed
95
101
  attr_accessor :ignore_method
96
102
 
97
103
  # the crud type of the (eventual?) action. different than :method, because this crud action may not be imminent.
@@ -121,7 +121,12 @@ module ActiveScaffold::DataStructures
121
121
  first_action = false
122
122
  end
123
123
  elsif controller.nil? || !skip_action_link(controller, link, *(Array(options[:for])))
124
- authorized = options[:for].nil? ? true : options[:for].authorized_for?(:crud_type => link.crud_type, :action => link.action)
124
+ security_method = link.security_method_set? || controller.respond_to?(link.security_method)
125
+ authorized = if security_method
126
+ controller.send(link.security_method, *args)
127
+ else
128
+ options[:for].nil? ? true : options[:for].authorized_for?(:crud_type => link.crud_type, :action => link.action)
129
+ end
125
130
  yield(self, link, {:authorized => authorized, :first_action => first_action, :level => options[:level]})
126
131
  first_action = false
127
132
  end
@@ -173,7 +178,7 @@ module ActiveScaffold::DataStructures
173
178
  protected
174
179
 
175
180
  def skip_action_link(controller, link, *args)
176
- (!link.ignore_method.nil? && controller.respond_to?(link.ignore_method) && controller.send(link.ignore_method, *args)) || ((link.security_method_set? or controller.respond_to? link.security_method) and !controller.send(link.security_method, *args))
181
+ !link.ignore_method.nil? && controller.respond_to?(link.ignore_method) && controller.send(link.ignore_method, *args)
177
182
  end
178
183
 
179
184
  # called during clone or dup. makes the clone/dup deeper.
@@ -179,7 +179,10 @@ module ActiveScaffold::DataStructures
179
179
  # describes how to search on a column
180
180
  # search = true default, uses intelligent search sql
181
181
  # search = "CONCAT(a, b)" define your own sql for searching. this should be the "left-side" of a WHERE condition. the operator and value will be supplied by ActiveScaffold.
182
- attr_writer :search_sql
182
+ # search = [:a, :b] searches in both fields
183
+ def search_sql=(value)
184
+ @search_sql = (value == true || value.is_a?(Proc)) ? value : Array(value)
185
+ end
183
186
  def search_sql
184
187
  self.initialize_search_sql if @search_sql === true
185
188
  @search_sql
@@ -281,6 +284,7 @@ module ActiveScaffold::DataStructures
281
284
  # instantiation is handled internally through the DataStructures::Columns object
282
285
  def initialize(name, active_record_class) #:nodoc:
283
286
  self.name = name.to_sym
287
+ @tableless = active_record_class < ActiveScaffold::Tableless
284
288
  @column = active_record_class.columns_hash[self.name.to_s]
285
289
  @association = active_record_class.reflect_on_association(self.name)
286
290
  @autolink = !@association.nil?
@@ -352,11 +356,7 @@ module ActiveScaffold::DataStructures
352
356
  # we don't automatically enable method sorting for virtual columns because it's slow, and we expect fewer complaints this way.
353
357
  self.sort = false
354
358
  else
355
- if self.singular_association?
356
- self.sort = {:method => "#{self.name}.to_s"}
357
- elsif self.plural_association?
358
- self.sort = {:method => "#{self.name}.join(',')"}
359
- elsif @active_record_class.connection
359
+ if column && @tableless
360
360
  self.sort = {:sql => self.field}
361
361
  else
362
362
  self.sort = false
@@ -367,9 +367,9 @@ module ActiveScaffold::DataStructures
367
367
  def initialize_search_sql
368
368
  self.search_sql = unless self.virtual?
369
369
  if association.nil?
370
- self.field.to_s unless @active_record_class.connection.nil?
370
+ self.field.to_s unless @tableless
371
371
  elsif !self.polymorphic_association?
372
- [association.klass.quoted_table_name, association.klass.quoted_primary_key].join('.') unless association.klass.connection.nil?
372
+ [association.klass.quoted_table_name, association.klass.quoted_primary_key].join('.') unless association.klass < ActiveScaffold::Tableless
373
373
  end
374
374
  end
375
375
  end
@@ -6,7 +6,11 @@ module ActiveScaffold::DataStructures
6
6
  nested_info[:name] = (params[:association] || params[:named_scope]).to_sym
7
7
  nested_info[:parent_scaffold] = "#{params[:parent_scaffold].to_s.camelize}Controller".constantize
8
8
  nested_info[:parent_model] = nested_info[:parent_scaffold].active_scaffold_config.model
9
- nested_info[:parent_id] = params[nested_info[:parent_model].name.foreign_key]
9
+ nested_info[:parent_id] = if params[:association].nil?
10
+ params[nested_info[:parent_model].name.foreign_key]
11
+ else
12
+ params[nested_info[:parent_model].reflect_on_association(params[:association].to_sym).active_record.name.foreign_key]
13
+ end
10
14
  if nested_info[:parent_id]
11
15
  unless params[:association].nil?
12
16
  ActiveScaffold::DataStructures::NestedInfoAssociation.new(model, nested_info)
@@ -15,8 +15,6 @@ module ActionController #:nodoc:
15
15
  end
16
16
  end
17
17
  alias_method_chain :render, :active_scaffold
18
-
19
- # Rails 2.x implementation is post-initialization on :active_scaffold method
20
18
  end
21
19
  end
22
20
 
@@ -0,0 +1,7 @@
1
+ module ActionController #:nodoc:
2
+ class Base
3
+ def deny_access
4
+ head :unauthorized
5
+ end
6
+ end
7
+ end
@@ -17,13 +17,18 @@ module ActiveScaffold
17
17
 
18
18
  where_clauses = []
19
19
  columns.each do |column|
20
- where_clauses << ((column.column.nil? || column.column.text?) ? "#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?" : "#{column.search_sql} = ?")
20
+ Array(column.search_sql).each do |search_sql|
21
+ where_clauses << "#{search_sql} #{(column.column.nil? || column.column.text?) ? ActiveScaffold::Finder.like_operator : '='} ?"
22
+ end
21
23
  end
22
24
  phrase = where_clauses.join(' OR ')
23
25
 
24
26
  tokens.collect do |value|
25
27
  columns.inject([phrase]) do |condition, column|
26
- condition.push((column.column.nil? || column.column.text?) ? like_pattern.sub('?', value) : column.column.type_cast(value))
28
+ Array(column.search_sql).size.times do
29
+ condition.push((column.column.nil? || column.column.text?) ? like_pattern.sub('?', value) : column.column.type_cast(value))
30
+ end
31
+ condition
27
32
  end
28
33
  end
29
34
  end
@@ -39,32 +44,37 @@ module ActiveScaffold
39
44
  return unless column and column.search_sql and not value.blank?
40
45
  search_ui = column.search_ui || column.column.try(:type)
41
46
  begin
42
- if search_ui && self.respond_to?("condition_for_#{search_ui}_type")
47
+ sql, *values = if search_ui && self.respond_to?("condition_for_#{search_ui}_type")
43
48
  self.send("condition_for_#{search_ui}_type", column, value, like_pattern)
44
49
  else
45
- unless column.search_sql.instance_of? Proc
50
+ if column.search_sql.instance_of? Proc
51
+ column.search_sql.call(value)
52
+ else
46
53
  case search_ui
47
- when :boolean, :checkbox
48
- ["#{column.search_sql} = ?", column.column.type_cast(value)]
49
- when :integer, :decimal, :float
50
- condition_for_numeric(column, value)
51
- when :string, :range
52
- condition_for_range(column, value, like_pattern)
53
- when :date, :time, :datetime, :timestamp
54
- condition_for_datetime(column, value)
55
- when :select, :multi_select, :country, :usa_state
56
- ["#{column.search_sql} in (?)", Array(value)]
54
+ when :boolean, :checkbox
55
+ ["%{search_sql} = ?", column.column ? column.column.type_cast(value) : value]
56
+ when :integer, :decimal, :float
57
+ condition_for_numeric(column, value)
58
+ when :string, :range
59
+ condition_for_range(column, value, like_pattern)
60
+ when :date, :time, :datetime, :timestamp
61
+ condition_for_datetime(column, value)
62
+ when :select, :multi_select, :country, :usa_state
63
+ ["%{search_sql} in (?)", [Array(value)]]
64
+ else
65
+ if column.column.nil? || column.column.text?
66
+ ["%{search_sql} #{ActiveScaffold::Finder.like_operator} ?", like_pattern.sub('?', value)]
57
67
  else
58
- if column.column.nil? || column.column.text?
59
- ["#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?", like_pattern.sub('?', value)]
60
- else
61
- ["#{column.search_sql} = ?", column.column.type_cast(value)]
62
- end
68
+ ["%{search_sql} = ?", column.column.type_cast(value)]
69
+ end
63
70
  end
64
- else
65
- column.search_sql.call(value)
66
71
  end
67
72
  end
73
+ return nil unless sql
74
+
75
+ conditions = [column.search_sql.collect { |search_sql| sql % {:search_sql => search_sql} }.join(' OR ')]
76
+ conditions += values*column.search_sql.size if values.present?
77
+ conditions
68
78
  rescue Exception => e
69
79
  logger.error Time.now.to_s + "#{e.inspect} -- on the ActiveScaffold column :#{column.name}, search_ui = #{search_ui} in #{self.name}"
70
80
  raise e
@@ -73,33 +83,33 @@ module ActiveScaffold
73
83
 
74
84
  def condition_for_numeric(column, value)
75
85
  if !value.is_a?(Hash)
76
- ["#{column.search_sql} = ?", condition_value_for_numeric(column, value)]
86
+ ["%{search_sql} = ?", condition_value_for_numeric(column, value)]
77
87
  elsif value[:from].blank? or not ActiveScaffold::Finder::NumericComparators.include?(value[:opt])
78
88
  nil
79
89
  elsif value[:opt] == 'BETWEEN'
80
- ["#{column.search_sql} BETWEEN ? AND ?", condition_value_for_numeric(column, value[:from]), condition_value_for_numeric(column, value[:to])]
81
- else
82
- ["#{column.search_sql} #{value[:opt]} ?", condition_value_for_numeric(column, value[:from])]
90
+ ["(%{search_sql} BETWEEN ? AND ?)", condition_value_for_numeric(column, value[:from]), condition_value_for_numeric(column, value[:to])]
91
+ else
92
+ ["%{search_sql} #{value[:opt]} ?", condition_value_for_numeric(column, value[:from])]
83
93
  end
84
94
  end
85
95
 
86
96
  def condition_for_range(column, value, like_pattern = nil)
87
97
  if !value.is_a?(Hash)
88
98
  if column.column.nil? || column.column.text?
89
- ["#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?", like_pattern.sub('?', value)]
99
+ ["%{search_sql} #{ActiveScaffold::Finder.like_operator} ?", like_pattern.sub('?', value)]
90
100
  else
91
- ["#{column.search_sql} = ?", column.column.type_cast(value)]
101
+ ["%{search_sql} = ?", column.column.type_cast(value)]
92
102
  end
93
103
  elsif ActiveScaffold::Finder::NullComparators.include?(value[:opt])
94
104
  condition_for_null_type(column, value[:opt], like_pattern)
95
105
  elsif value[:from].blank?
96
106
  nil
97
107
  elsif ActiveScaffold::Finder::StringComparators.values.include?(value[:opt])
98
- ["#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?", value[:opt].sub('?', value[:from])]
108
+ ["%{search_sql} #{ActiveScaffold::Finder.like_operator} ?", value[:opt].sub('?', value[:from])]
99
109
  elsif value[:opt] == 'BETWEEN'
100
- ["#{column.search_sql} BETWEEN ? AND ?", value[:from], value[:to]]
110
+ ["(%{search_sql} BETWEEN ? AND ?)", value[:from], value[:to]]
101
111
  elsif ActiveScaffold::Finder::NumericComparators.include?(value[:opt])
102
- ["#{column.search_sql} #{value[:opt]} ?", value[:from]]
112
+ ["%{search_sql} #{value[:opt]} ?", value[:from]]
103
113
  else
104
114
  nil
105
115
  end
@@ -157,37 +167,45 @@ module ActiveScaffold
157
167
  value
158
168
  end
159
169
  end
170
+
171
+ def datetime_conversion_for_condition(column)
172
+ if column.column
173
+ column.column.type == :date ? :to_date : :to_time
174
+ else
175
+ :to_time
176
+ end
177
+ end
160
178
 
161
179
  def condition_for_datetime(column, value, like_pattern = nil)
162
- conversion = column.column.type == :date ? :to_date : :to_time
180
+ conversion = datetime_conversion_for_condition(column)
163
181
  from_value = condition_value_for_datetime(value[:from], conversion)
164
182
  to_value = condition_value_for_datetime(value[:to], conversion)
165
183
 
166
184
  if from_value.nil? and to_value.nil?
167
185
  nil
168
186
  elsif !from_value
169
- ["#{column.search_sql} <= ?", to_value.to_s(:db)]
187
+ ["%{search_sql} <= ?", to_value.to_s(:db)]
170
188
  elsif !to_value
171
- ["#{column.search_sql} >= ?", from_value.to_s(:db)]
189
+ ["%{search_sql} >= ?", from_value.to_s(:db)]
172
190
  else
173
- ["#{column.search_sql} BETWEEN ? AND ?", from_value.to_s(:db), to_value.to_s(:db)]
191
+ ["%{search_sql} BETWEEN ? AND ?", from_value.to_s(:db), to_value.to_s(:db)]
174
192
  end
175
193
  end
176
194
 
177
195
  def condition_for_record_select_type(column, value, like_pattern = nil)
178
196
  if value.is_a?(Array)
179
- ["#{column.search_sql} IN (?)", value]
197
+ ["%{search_sql} IN (?)", value]
180
198
  else
181
- ["#{column.search_sql} = ?", value]
199
+ ["%{search_sql} = ?", value]
182
200
  end
183
201
  end
184
202
 
185
203
  def condition_for_null_type(column, value, like_pattern = nil)
186
204
  case value.to_sym
187
205
  when :null
188
- ["#{column.search_sql} is null"]
206
+ ["%{search_sql} is null", []]
189
207
  when :not_null
190
- ["#{column.search_sql} is not null"]
208
+ ["%{search_sql} is not null", []]
191
209
  else
192
210
  nil
193
211
  end
@@ -218,8 +236,8 @@ module ActiveScaffold
218
236
  :ends_with => '%?'
219
237
  }
220
238
  NullComparators = [
221
- :null,
222
- :not_null
239
+ 'null',
240
+ 'not_null'
223
241
  ]
224
242
 
225
243
 
@@ -73,8 +73,11 @@ module ActiveScaffold
73
73
  # Fix for keeping unique IDs in subform
74
74
  id_control = "record_#{column.name}_#{[params[:eid], params[:id]].compact.join '_'}"
75
75
  id_control += scope_id(scope) if scope
76
+
77
+ classes = "#{column.name}-input"
78
+ classes += ' numeric-input' if column.number?
76
79
 
77
- { :name => name, :class => "#{column.name}-input", :id => id_control}.merge(options)
80
+ { :name => name, :class => classes, :id => id_control}.merge(options)
78
81
  end
79
82
 
80
83
  def update_columns_options(column, scope, options)
@@ -179,10 +179,12 @@ module ActiveScaffold
179
179
  options_for_select(select_options, opt_value),
180
180
  :id => "#{options[:id]}_opt",
181
181
  :class => "as_search_range_option")
182
- html << ' ' << text_field_tag("#{options[:name]}[from]", from_value, active_scaffold_input_text_options(:id => options[:id], :size => text_field_size))
183
- html << ' ' << content_tag(:span, (' - ' + text_field_tag("#{options[:name]}[to]", to_value,
182
+ html << content_tag("span", :id => "#{options[:id]}_numeric", :style => ActiveScaffold::Finder::NullComparators.include?(opt_value) ? "display: none" : nil) do
183
+ text_field_tag("#{options[:name]}[from]", from_value, active_scaffold_input_text_options(:id => options[:id], :size => text_field_size)) <<
184
+ content_tag(:span, (' - ' + text_field_tag("#{options[:name]}[to]", to_value,
184
185
  active_scaffold_input_text_options(:id => "#{options[:id]}_to", :size => text_field_size))).html_safe,
185
186
  :id => "#{options[:id]}_between", :class => "as_search_range_between", :style => (opt_value == 'BETWEEN') ? nil : "display: none")
187
+ end
186
188
  content_tag :span, html, :class => 'search_range'
187
189
  end
188
190
  alias_method :active_scaffold_search_integer, :active_scaffold_search_range
@@ -146,6 +146,7 @@ module ActiveScaffold
146
146
  html_options[:data][:confirm] = link.confirm(record.try(:to_label)) if link.confirm?
147
147
  html_options[:data][:position] = link.position if link.position and link.inline?
148
148
  html_options[:data][:action] = link.action if link.inline?
149
+ html_options[:data][:'cancel-refresh'] = true if link.inline? and link.refresh_on_close
149
150
  if link.popup?
150
151
  html_options[:data][:popup] = true
151
152
  html_options[:target] = '_blank'
@@ -189,11 +190,13 @@ module ActiveScaffold
189
190
  end
190
191
 
191
192
  def url_options_for_nested_link(column, record, link, url_options, options = {})
192
- if column && column.association
193
+ if column && column.association
194
+ url_options[:parent_scaffold] = controller_path
193
195
  url_options[column.association.active_record.name.foreign_key.to_sym] = url_options.delete(:id)
194
196
  url_options[:id] = record.send(column.association.name).id if column.singular_association? && record.send(column.association.name).present?
195
197
  url_options[:eid] = nil # needed for nested scaffolds open from an embedded scaffold
196
198
  elsif link.parameters && link.parameters[:named_scope]
199
+ url_options[:parent_scaffold] = controller_path
197
200
  url_options[active_scaffold_config.model.name.foreign_key.to_sym] = url_options.delete(:id)
198
201
  url_options[:eid] = nil # needed for nested scaffolds open from an embedded scaffold
199
202
  end
@@ -46,7 +46,6 @@ class ActiveScaffold::Tableless < ActiveRecord::Base
46
46
 
47
47
  def self.columns; @columns ||= []; end
48
48
  def self.table_name; @table_name ||= ActiveModel::Naming.plural(self); end
49
- def self.connection; nil; end
50
49
  def self.table_exists?; true; end
51
50
  self.abstract_class = true
52
51
  class << self
@@ -2,7 +2,7 @@ module ActiveScaffold
2
2
  module Version
3
3
  MAJOR = 3
4
4
  MINOR = 2
5
- PATCH = 12
5
+ PATCH = 13
6
6
 
7
7
  STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
8
  end
@@ -5,6 +5,7 @@ module Rails
5
5
  module Generators
6
6
  class ActiveScaffoldGenerator < ResourceGenerator #metagenerator
7
7
  remove_hook_for :resource_controller
8
+ remove_hook_for :resource_route
8
9
  remove_class_option :actions
9
10
 
10
11
  def add_resource_route
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_scaffold
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 2
9
- - 12
10
- version: 3.2.12
9
+ - 13
10
+ version: 3.2.13
11
11
  platform: ruby
12
12
  authors:
13
13
  - Many, see README
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-06-13 00:00:00 Z
18
+ date: 2012-07-03 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  type: :development
@@ -29,8 +29,8 @@ dependencies:
29
29
  - 0
30
30
  version: "0"
31
31
  version_requirements: *id001
32
- prerelease: false
33
32
  name: shoulda
33
+ prerelease: false
34
34
  - !ruby/object:Gem::Dependency
35
35
  type: :development
36
36
  requirement: &id002 !ruby/object:Gem::Requirement
@@ -45,8 +45,8 @@ dependencies:
45
45
  - 0
46
46
  version: 1.0.0
47
47
  version_requirements: *id002
48
- prerelease: false
49
48
  name: bundler
49
+ prerelease: false
50
50
  - !ruby/object:Gem::Dependency
51
51
  type: :development
52
52
  requirement: &id003 !ruby/object:Gem::Requirement
@@ -59,8 +59,8 @@ dependencies:
59
59
  - 0
60
60
  version: "0"
61
61
  version_requirements: *id003
62
- prerelease: false
63
62
  name: rcov
63
+ prerelease: false
64
64
  - !ruby/object:Gem::Dependency
65
65
  type: :runtime
66
66
  requirement: &id004 !ruby/object:Gem::Requirement
@@ -75,8 +75,8 @@ dependencies:
75
75
  - 3
76
76
  version: 3.1.3
77
77
  version_requirements: *id004
78
- prerelease: false
79
78
  name: rails
79
+ prerelease: false
80
80
  description: Save time and headaches, and create a more easily maintainable set of pages, with ActiveScaffold. ActiveScaffold handles all your CRUD (create, read, update, delete) user interface needs, leaving you more time to focus on more challenging (and interesting!) problems.
81
81
  email: activescaffold@googlegroups.com
82
82
  executables: []
@@ -274,6 +274,7 @@ files:
274
274
  - lib/active_scaffold/data_structures/sorting.rb
275
275
  - lib/active_scaffold/engine.rb
276
276
  - lib/active_scaffold/extensions/action_controller_rendering.rb
277
+ - lib/active_scaffold/extensions/action_controller_rescueing.rb
277
278
  - lib/active_scaffold/extensions/action_view_rendering.rb
278
279
  - lib/active_scaffold/extensions/active_association_reflection.rb
279
280
  - lib/active_scaffold/extensions/active_record_offset.rb
@@ -442,7 +443,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
442
443
  requirements: []
443
444
 
444
445
  rubyforge_project:
445
- rubygems_version: 1.8.23
446
+ rubygems_version: 1.8.10
446
447
  signing_key:
447
448
  specification_version: 3
448
449
  summary: Rails 3.1 Version of activescaffold supporting prototype and jquery