active_scaffold 3.3.2 → 3.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +9 -0
  3. data/app/assets/javascripts/active_scaffold.js.erb +5 -2
  4. data/app/assets/javascripts/jquery/active_scaffold.js +4 -6
  5. data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +16 -14
  6. data/app/assets/javascripts/prototype/active_scaffold.js +0 -5
  7. data/app/assets/stylesheets/active_scaffold.css.scss +1 -1
  8. data/app/assets/stylesheets/active_scaffold_jquery_ui.css.erb +7 -0
  9. data/lib/active_scaffold.rb +1 -1
  10. data/lib/active_scaffold/actions/update.rb +2 -1
  11. data/lib/active_scaffold/attribute_params.rb +2 -2
  12. data/lib/active_scaffold/bridges/date_picker.rb +1 -1
  13. data/lib/active_scaffold/config/core.rb +0 -2
  14. data/lib/active_scaffold/config/nested.rb +6 -3
  15. data/lib/active_scaffold/constraints.rb +2 -2
  16. data/lib/active_scaffold/data_structures/action_columns.rb +68 -72
  17. data/lib/active_scaffold/data_structures/column.rb +7 -3
  18. data/lib/active_scaffold/data_structures/sorting.rb +2 -1
  19. data/lib/active_scaffold/finder.rb +2 -14
  20. data/lib/active_scaffold/helpers/form_column_helpers.rb +1 -0
  21. data/lib/active_scaffold/helpers/list_column_helpers.rb +1 -1
  22. data/lib/active_scaffold/helpers/pagination_helpers.rb +1 -1
  23. data/lib/active_scaffold/helpers/search_column_helpers.rb +2 -2
  24. data/lib/active_scaffold/helpers/view_helpers.rb +7 -5
  25. data/lib/active_scaffold/tableless.rb +2 -2
  26. data/lib/active_scaffold/version.rb +1 -1
  27. data/test/bridges/bridge_test.rb +22 -33
  28. data/test/bridges/date_picker_test.rb +29 -0
  29. data/test/bridges/paperclip_test.rb +10 -11
  30. data/test/bridges/tiny_mce_test.rb +7 -7
  31. data/test/{bridges/company.rb → company.rb} +14 -13
  32. data/test/config/base_test.rb +14 -12
  33. data/test/config/core_test.rb +59 -53
  34. data/test/config/create_test.rb +56 -54
  35. data/test/config/delete_test.rb +31 -29
  36. data/test/config/field_search_test.rb +45 -43
  37. data/test/config/list_test.rb +119 -117
  38. data/test/config/nested_test.rb +50 -58
  39. data/test/config/search_test.rb +58 -56
  40. data/test/config/show_test.rb +42 -40
  41. data/test/config/subform_test.rb +15 -13
  42. data/test/config/update_test.rb +40 -38
  43. data/test/const_mocker.rb +14 -18
  44. data/test/data_structures/action_columns_test.rb +3 -3
  45. data/test/data_structures/action_link_test.rb +1 -1
  46. data/test/data_structures/action_links_test.rb +3 -3
  47. data/test/data_structures/actions_test.rb +2 -2
  48. data/test/data_structures/association_column_test.rb +5 -6
  49. data/test/data_structures/column_test.rb +8 -4
  50. data/test/data_structures/columns_test.rb +2 -3
  51. data/test/data_structures/error_message_test.rb +2 -2
  52. data/test/data_structures/set_test.rb +2 -3
  53. data/test/data_structures/sorting_test.rb +1 -2
  54. data/test/data_structures/standard_column_test.rb +2 -3
  55. data/test/data_structures/validation_reflection_test.rb +51 -0
  56. data/test/data_structures/virtual_column_test.rb +1 -1
  57. data/test/extensions/active_record_test.rb +2 -3
  58. data/test/extensions/array_test.rb +2 -2
  59. data/test/helpers/form_column_helpers_test.rb +6 -6
  60. data/test/helpers/list_column_helpers_test.rb +4 -1
  61. data/test/helpers/pagination_helpers_test.rb +7 -3
  62. data/test/misc/active_record_permissions_test.rb +1 -1
  63. data/test/misc/attribute_params_test.rb +3 -4
  64. data/test/misc/configurable_test.rb +2 -2
  65. data/test/misc/constraints_test.rb +29 -29
  66. data/test/misc/finder_test.rb +13 -10
  67. data/test/misc/lang_test.rb +1 -1
  68. data/test/mock_app/Rakefile +7 -0
  69. data/test/mock_app/config.ru +4 -0
  70. data/test/mock_app/config/application.rb +11 -0
  71. data/test/mock_app/config/boot.rb +6 -109
  72. data/test/mock_app/config/database.yml +2 -2
  73. data/test/mock_app/config/environment.rb +4 -42
  74. data/test/mock_app/config/environments/development.rb +21 -13
  75. data/test/mock_app/config/environments/production.rb +41 -20
  76. data/test/mock_app/config/environments/test.rb +27 -22
  77. data/test/mock_app/config/initializers/backtrace_silencers.rb +2 -2
  78. data/test/mock_app/config/initializers/inflections.rb +1 -1
  79. data/test/mock_app/config/initializers/secret_token.rb +7 -0
  80. data/test/mock_app/config/initializers/session_store.rb +2 -9
  81. data/test/mock_app/config/initializers/wrap_parameters.rb +14 -0
  82. data/test/mock_app/config/routes.rb +2 -42
  83. data/test/model_stub.rb +2 -3
  84. data/test/test_helper.rb +13 -11
  85. data/vendor/assets/stylesheets/jquery-ui-theme.css.erb +47 -0
  86. data/vendor/assets/stylesheets/jquery-ui.css +2 -36
  87. metadata +92 -103
  88. data/test/bridges/active_scaffold_dependent_protect_test.rb +0 -34
  89. data/test/bridges/unobtrusive_date_picker_test.rb +0 -49
  90. data/test/bridges/validation_reflection_test.rb +0 -57
  91. data/test/mock_app/config/initializers/new_rails_defaults.rb +0 -19
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 33153bffc906bb3250c092c0e566b40ad97e8069
4
+ data.tar.gz: f281d1909186146d7d937fc1f8592c66f27bac8c
5
+ SHA512:
6
+ metadata.gz: 09f9192c00510733988bf1c61ed16d1da71b465cdba3256549a4f96bd2133dbac1ddbcfb23db93978ca7fa863712fe46619c3cb23ed7c55fd17326aa32fbaa40
7
+ data.tar.gz: 4c558220d20826e976986d4b5cf9c51571179a74e27394c69aee41ae43088f3960386ce403757fed4305d69a4c6cabae81a511802be82175484111292c0c2003
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ = 3.3.3
2
+ - Allow to override select options in active_scaffold_search_select
3
+ - Load effects from jQuery UI when using jquery-rails 3 gem
4
+ - Fix searching on nested scaffolds (broken on 3.3.2)
5
+ - Fix searching when includes is set to nil
6
+ - Send parent_controller for render_field requests on subforms for persisted records, as new records were already sending it
7
+ - Avoid loading some JS when jquery-ui is not available
8
+ - Load CSS from jquery ui rails gem
9
+
1
10
  = 3.3.2
2
11
  - Fix subforms inside subforms
3
12
  - Fix draggable for jquery-rails 3 gem
@@ -4,18 +4,21 @@
4
4
  <% if Jquery::Rails.const_defined? 'JQUERY_UI_VERSION' %>
5
5
  <% require_asset "jquery-ui" %>
6
6
  <% require_asset "jquery-ui-timepicker-addon" %>
7
+ <% require_asset "jquery/date_picker_bridge" %>
8
+ <% require_asset "jquery/draggable_lists" %>
7
9
  <% elsif Jquery.const_defined? 'Ui' %>
8
10
  <% require_asset "jquery.ui.core" %>
11
+ <% require_asset "jquery.ui.effect" %>
9
12
  <% require_asset "jquery.ui.sortable" %>
10
13
  <% require_asset "jquery.ui.draggable" %>
11
14
  <% require_asset "jquery.ui.droppable" %>
12
15
  <% require_asset "jquery.ui.datepicker" %>
13
16
  <% require_asset "jquery-ui-timepicker-addon" %>
17
+ <% require_asset "jquery/date_picker_bridge" %>
18
+ <% require_asset "jquery/draggable_lists" %>
14
19
  <% end %>
15
20
  <% require_asset "jquery/active_scaffold" %>
16
21
  <% require_asset "jquery/jquery.editinplace" %>
17
- <% require_asset "jquery/date_picker_bridge" %>
18
- <% require_asset "jquery/draggable_lists" %>
19
22
  <% when :prototype %>
20
23
  <% require_asset "effects" %>
21
24
  <% require_asset "controls" %>
@@ -207,11 +207,6 @@ jQuery(document).ready(function($) {
207
207
  ActiveScaffold.delete_subform_record($(this).data('delete-id'));
208
208
  });
209
209
 
210
- jQuery(document).on('click', 'a[data-popup]', function(e) {
211
- window.open(jQuery(this).attr('href'));
212
- e.preventDefault();
213
- });
214
-
215
210
  jQuery(document).on("click", '.hover_click', function(event) {
216
211
  var element = jQuery(this);
217
212
  var ul_element = element.children('ul').first();
@@ -1080,6 +1075,10 @@ ActiveScaffold.ActionLink.Record = ActiveScaffold.ActionLink.Abstract.extend({
1080
1075
  }
1081
1076
 
1082
1077
  var colspan = this.target.children().length;
1078
+ if (content && this.position) {
1079
+ content = jQuery(content);
1080
+ content.find('.inline-adapter-cell:first').attr('colspan', colspan);
1081
+ }
1083
1082
  if (this.position == 'after') {
1084
1083
  this.target.after(content);
1085
1084
  this.set_adapter(this.target.next());
@@ -1091,7 +1090,6 @@ ActiveScaffold.ActionLink.Record = ActiveScaffold.ActionLink.Abstract.extend({
1091
1090
  else {
1092
1091
  return false;
1093
1092
  }
1094
- this.adapter.find('.inline-adapter-cell:first').attr('colspan', colspan);
1095
1093
  ActiveScaffold.highlight(this.adapter.find('td'));
1096
1094
  },
1097
1095
 
@@ -1,23 +1,25 @@
1
1
  <%# encoding: utf-8 %>
2
2
  <%= ActiveScaffold::Bridges[:date_picker].localization %>
3
- Object.getPrototypeOf($.datepicker)._attachDatepicker_without_inlineSettings = Object.getPrototypeOf($.datepicker)._attachDatepicker;
4
- $.extend(Object.getPrototypeOf($.datepicker), {
5
- _attachDatepicker: function(target, settings) {
6
- var inlineSettings = {}, $target = $(target);
7
- for (var attrName in this._defaults) {
8
- if(this._defaults.hasOwnProperty(attrName)){
9
- var attrValue = $target.data(attrName.toLowerCase());
10
- if (attrValue) {
11
- try {
12
- inlineSettings[attrName] = eval(attrValue);
13
- } catch (err) {
14
- inlineSettings[attrName] = attrValue;
3
+ jQuery(function($) {
4
+ Object.getPrototypeOf($.datepicker)._attachDatepicker_without_inlineSettings = Object.getPrototypeOf($.datepicker)._attachDatepicker;
5
+ $.extend(Object.getPrototypeOf($.datepicker), {
6
+ _attachDatepicker: function(target, settings) {
7
+ var inlineSettings = {}, $target = $(target);
8
+ for (var attrName in this._defaults) {
9
+ if(this._defaults.hasOwnProperty(attrName)){
10
+ var attrValue = $target.data(attrName.toLowerCase());
11
+ if (attrValue) {
12
+ try {
13
+ inlineSettings[attrName] = eval(attrValue);
14
+ } catch (err) {
15
+ inlineSettings[attrName] = attrValue;
16
+ }
15
17
  }
16
18
  }
17
19
  }
20
+ this._attachDatepicker_without_inlineSettings(target, $.extend({}, settings || {}, inlineSettings));
18
21
  }
19
- this._attachDatepicker_without_inlineSettings(target, $.extend({}, settings || {}, inlineSettings));
20
- }
22
+ });
21
23
  });
22
24
  jQuery(document).on("focus", "input.date_picker", function(){
23
25
  var date_picker = jQuery(this);
@@ -282,11 +282,6 @@ document.observe("dom:loaded", function() {
282
282
  Element[element.value == 'REPLACE' ? 'hide' : 'show'](element.next('span'));
283
283
  return true;
284
284
  });
285
- document.on("click", "a[data-popup]", function(event, element) {
286
- if (event.stopped) return;
287
- window.open($(element).href);
288
- event.stop();
289
- });
290
285
  document.on("click", ".hover_click", function(event, element) {
291
286
  var ul_element = element.down('ul');
292
287
  if (ul_element.getStyle('display') === 'none') {
@@ -9,6 +9,6 @@
9
9
 
10
10
  @import 'active_scaffold_layout';
11
11
  @import 'active_scaffold_images';
12
- @import 'jquery-ui';
12
+ @import 'active_scaffold_jquery_ui';
13
13
  @import 'active_scaffold_extensions';
14
14
  @import 'active_scaffold_colors';
@@ -0,0 +1,7 @@
1
+ <% if Jquery::Rails.const_defined? 'JQUERY_UI_VERSION' %>
2
+ <% require_asset "jquery-ui" %>
3
+ <% require_asset "jquery-ui-theme" %>
4
+ <% elsif Jquery.const_defined? 'Ui' %>
5
+ <% require_asset "jquery.ui.datepicker" %>
6
+ <% require_asset "jquery-ui-theme" %>
7
+ <% end %>
@@ -228,7 +228,7 @@ module ActiveScaffold
228
228
  active_scaffold_config.action_links.collection.delete('new')
229
229
  active_scaffold_config.sti_children.each do |child|
230
230
  new_sti_link = Marshal.load(Marshal.dump(new_action_link)) # deep clone
231
- new_sti_link.label = child.to_s.camelize.constantize.model_name.human
231
+ new_sti_link.label = as_(:create_model, :model => child.to_s.camelize.constantize.model_name.human)
232
232
  new_sti_link.parameters = {:parent_sti => controller_path}
233
233
  new_sti_link.controller = Proc.new { active_scaffold_controller_for(child.to_s.camelize.constantize).controller_path }
234
234
  active_scaffold_config.action_links.collection.create.add(new_sti_link)
@@ -53,11 +53,12 @@ module ActiveScaffold::Actions
53
53
  if update_refresh_list?
54
54
  do_refresh_list
55
55
  else
56
+ @updated_record = @record
56
57
  # get_row so associations are cached like in list action
57
58
  @record = get_row rescue nil # if record doesn't fullfil current conditions remove it from list
58
59
  end
59
60
  end
60
- flash.now[:info] = as_(:updated_model, :model => @record.to_label) if active_scaffold_config.update.persistent
61
+ flash.now[:info] = as_(:updated_model, :model => (@updated_record || @record).to_label) if active_scaffold_config.update.persistent
61
62
  end
62
63
  render :action => 'on_update'
63
64
  end
@@ -129,8 +129,8 @@ module ActiveScaffold
129
129
  end
130
130
  elsif column.plural_association?
131
131
  column_plural_assocation_value_from_value(column, Array(value))
132
- elsif column.number? && [:i18n_number, :currency].include?(column.options[:format]) && column.form_ui != :number
133
- self.class.i18n_number_to_native_format(value)
132
+ elsif column.number? && column.options[:format] && column.form_ui != :number
133
+ column.number_to_native(value)
134
134
  else
135
135
  # convert empty strings into nil. this works better with 'null => true' columns (and validations),
136
136
  # and 'null => false' columns should just convert back to an empty string.
@@ -8,7 +8,7 @@ module ActiveScaffold::Bridges
8
8
  ActiveScaffold.js_framework == :jquery && jquery_ui_included?
9
9
  end
10
10
  def self.jquery_ui_included?
11
- Jquery::Rails.const_defined?('JQUERY_UI_VERSION') || Jquery.const_defined?('Ui')
11
+ Jquery::Rails.const_defined?('JQUERY_UI_VERSION') || Jquery.const_defined?('Ui') if Object.const_defined?('Jquery')
12
12
  end
13
13
  def self.localization
14
14
  "jQuery(function($){
@@ -173,8 +173,6 @@ module ActiveScaffold::Config
173
173
 
174
174
  # To be called after your finished configuration
175
175
  def _load_action_columns
176
- #ActiveScaffold::DataStructures::ActionColumns.class_eval {include ActiveScaffold::DataStructures::ActionColumns::AfterConfiguration}
177
-
178
176
  # then, register the column objects
179
177
  self.actions.each do |action_name|
180
178
  action = self.send(action_name)
@@ -25,7 +25,7 @@ module ActiveScaffold::Config
25
25
  # Add a nested ActionLink
26
26
  def add_link(attribute, options = {})
27
27
  column = @core.columns[attribute.to_sym]
28
- unless column.nil? || column.association.nil?
28
+ if column && column.association
29
29
  label = if column.polymorphic_association?
30
30
  column.label
31
31
  else
@@ -35,8 +35,11 @@ module ActiveScaffold::Config
35
35
  action_group = options.delete(:action_group) || self.action_group
36
36
  action_link = @core.link_for_association(column, options)
37
37
  @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
38
- else
39
- # TODO: raise exception
38
+ action_link
39
+ elsif column.nil?
40
+ raise ArgumentError.new("unknown column #{attribute}")
41
+ elsif column.association.nil?
42
+ raise ArgumentError.new("column #{attribute} is not an association")
40
43
  end
41
44
  end
42
45
 
@@ -62,7 +62,7 @@ module ActiveScaffold
62
62
  elsif column.association
63
63
  if column.association.macro == :has_and_belongs_to_many
64
64
  active_scaffold_habtm_joins.concat column.includes
65
- else
65
+ elsif !column.association.options[:polymorphic]
66
66
  active_scaffold_includes.concat column.includes
67
67
  end
68
68
  hash_conditions.merge!(condition_from_association_constraint(column.association, v))
@@ -116,7 +116,7 @@ module ActiveScaffold
116
116
  condition = {"#{table}.#{field}" => value}
117
117
  if association.options[:polymorphic]
118
118
  raise ActiveScaffold::MalformedConstraint, polymorphic_constraint_error(association), caller unless params[:parent_model]
119
- condition["#{table}.#{association.name}_type"] = params[:parent_model].constantize.model.to_s
119
+ condition["#{table}.#{association.name}_type"] = params[:parent_model].constantize.to_s
120
120
  end
121
121
 
122
122
  condition
@@ -59,88 +59,84 @@ module ActiveScaffold::DataStructures
59
59
  Array(@set)
60
60
  end
61
61
 
62
- # A package of stuff to add after the configuration block. This is an attempt at making a certain level of functionality inaccessible during configuration, to reduce possible breakage from misuse.
63
- # The bulk of the package is a means of connecting the referential column set (ActionColumns) with the actual column objects (Columns). This lets us iterate over the set and yield real column objects.
64
- #module AfterConfiguration
65
- # Redefine the each method to yield actual Column objects.
66
- # It will skip constrained and unauthorized columns.
67
- #
68
- # Options:
69
- # * :flatten - whether to recursively iterate on nested sets. default is false.
70
- # * :for - the record (or class) being iterated over. used for column-level security. default is the class.
71
- def each(options = {}, &proc)
72
- options[:for] ||= @columns.active_record_class unless @columns.nil?
73
- self.unauthorized_columns = []
74
- @set.each do |item|
75
- unless item.is_a?(ActiveScaffold::DataStructures::ActionColumns) || @columns.nil?
76
- item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
77
- next if self.skip_column?(item, options)
78
- end
79
- if item.is_a? ActiveScaffold::DataStructures::ActionColumns
80
- if options[:flatten]
81
- item.each(options, &proc)
82
- elsif !options[:skip_groups]
83
- yield item
84
- end
85
- else
62
+ # Redefine the each method to yield actual Column objects.
63
+ # It will skip constrained and unauthorized columns.
64
+ #
65
+ # Options:
66
+ # * :flatten - whether to recursively iterate on nested sets. default is false.
67
+ # * :for - the record (or class) being iterated over. used for column-level security. default is the class.
68
+ def each(options = {}, &proc)
69
+ options[:for] ||= @columns.active_record_class unless @columns.nil?
70
+ self.unauthorized_columns = []
71
+ @set.each do |item|
72
+ unless item.is_a?(ActiveScaffold::DataStructures::ActionColumns) || @columns.nil?
73
+ item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
74
+ next if self.skip_column?(item, options)
75
+ end
76
+ if item.is_a? ActiveScaffold::DataStructures::ActionColumns
77
+ if options[:flatten]
78
+ item.each(options, &proc)
79
+ elsif !options[:skip_groups]
86
80
  yield item
87
81
  end
82
+ else
83
+ yield item
88
84
  end
89
85
  end
90
-
91
- def collect_visible(options = {}, &proc)
92
- columns = []
93
- options[:for] ||= @columns.active_record_class
94
- self.unauthorized_columns = []
95
- @set.each do |item|
96
- unless item.is_a? ActiveScaffold::DataStructures::ActionColumns || @columns.nil?
97
- item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
98
- next if self.skip_column?(item, options)
99
- end
100
- if item.is_a? ActiveScaffold::DataStructures::ActionColumns and options.has_key?(:flatten) and options[:flatten]
101
- columns += item.collect_visible(options, &proc)
102
- else
103
- columns << (block_given? ? yield(item) : item)
104
- end
86
+ end
87
+
88
+ def collect_visible(options = {}, &proc)
89
+ columns = []
90
+ options[:for] ||= @columns.active_record_class
91
+ self.unauthorized_columns = []
92
+ @set.each do |item|
93
+ unless item.is_a? ActiveScaffold::DataStructures::ActionColumns || @columns.nil?
94
+ item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
95
+ next if self.skip_column?(item, options)
105
96
  end
106
- columns
107
- end
108
-
109
- def skip_column?(column, options)
110
- result = false
111
- # skip if this matches a constrained column
112
- result = true if constraint_columns.include?(column.name.to_sym)
113
- # skip this field if it's not authorized
114
- unless options[:for].authorized_for?(:action => options[:action], :crud_type => options[:crud_type] || self.action.try(:crud_type), :column => column.name)
115
- self.unauthorized_columns << column.name.to_sym
116
- result = true
97
+ if item.is_a? ActiveScaffold::DataStructures::ActionColumns and options.has_key?(:flatten) and options[:flatten]
98
+ columns += item.collect_visible(options, &proc)
99
+ else
100
+ columns << (block_given? ? yield(item) : item)
117
101
  end
118
- return result
119
102
  end
120
-
121
- # registers a set of column objects (recursively, for all nested ActionColumns)
122
- def set_columns(columns)
123
- @columns = columns
124
- # iterate over @set instead of self to avoid dealing with security queries
125
- @set.each do |item|
126
- item.set_columns(columns) if item.respond_to? :set_columns
127
- end
103
+ columns
104
+ end
105
+
106
+ def skip_column?(column, options)
107
+ result = false
108
+ # skip if this matches a constrained column
109
+ result = true if constraint_columns.include?(column.name.to_sym)
110
+ # skip this field if it's not authorized
111
+ unless options[:for].authorized_for?(:action => options[:action], :crud_type => options[:crud_type] || self.action.try(:crud_type), :column => column.name)
112
+ self.unauthorized_columns << column.name.to_sym
113
+ result = true
128
114
  end
115
+ return result
116
+ end
129
117
 
130
- attr_writer :constraint_columns
131
- def constraint_columns
132
- @constraint_columns ||= []
118
+ # registers a set of column objects (recursively, for all nested ActionColumns)
119
+ def set_columns(columns)
120
+ @columns = columns
121
+ # iterate over @set instead of self to avoid dealing with security queries
122
+ @set.each do |item|
123
+ item.set_columns(columns) if item.respond_to? :set_columns
133
124
  end
134
-
135
- attr_writer :unauthorized_columns
136
- def unauthorized_columns
137
- @unauthorized_columns ||= []
138
- end
139
-
140
- def length
141
- ((@set - self.constraint_columns) - self.unauthorized_columns).length
142
- end
143
- #end
125
+ end
126
+
127
+ attr_writer :constraint_columns
128
+ def constraint_columns
129
+ @constraint_columns ||= []
130
+ end
131
+
132
+ attr_writer :unauthorized_columns
133
+ def unauthorized_columns
134
+ @unauthorized_columns ||= []
135
+ end
136
+
137
+ def length
138
+ ((@set - self.constraint_columns) - self.unauthorized_columns).length
139
+ end
144
140
 
145
141
  protected
146
142
 
@@ -177,7 +177,7 @@ module ActiveScaffold::DataStructures
177
177
  def includes=(value)
178
178
  @includes = case value
179
179
  when Array then value
180
- else [value] # automatically convert to an array
180
+ else value ? [value] : value # not convert nil to [nil]
181
181
  end
182
182
  end
183
183
 
@@ -201,14 +201,18 @@ module ActiveScaffold::DataStructures
201
201
  # 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.
202
202
  # search = [:a, :b] searches in both fields
203
203
  def search_sql=(value)
204
- @search_sql = (value == true || value.is_a?(Proc)) ? value : Array(value)
204
+ @search_sql = if value
205
+ (value == true || value.is_a?(Proc)) ? value : Array(value)
206
+ else
207
+ value
208
+ end
205
209
  end
206
210
  def search_sql
207
211
  self.initialize_search_sql if @search_sql === true
208
212
  @search_sql
209
213
  end
210
214
  def searchable?
211
- search_sql != false && search_sql != nil
215
+ !!search_sql
212
216
  end
213
217
 
214
218
  # to modify the default order of columns
@@ -35,8 +35,9 @@ module ActiveScaffold::DataStructures
35
35
  direction ||= 'ASC'
36
36
  direction = direction.to_s.upcase
37
37
  column = get_column(column_name)
38
+ raise ArgumentError, "Could not find column #{column_name}" if column.nil?
38
39
  raise ArgumentError, "Sorting direction unknown" unless [:ASC, :DESC].include? direction.to_sym
39
- @clauses << [column, direction.untaint] if column and column.sortable?
40
+ @clauses << [column, direction.untaint] if column.sortable?
40
41
  raise ArgumentError, "Can't mix :method- and :sql-based sorting" if mixed_sorting?
41
42
  end
42
43