active_scaffold 3.6.9 → 3.6.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1e1f178ccfe11c704e5064d0ee50bfa6a27d6aee4f478f478e6e0529a7e0683
4
- data.tar.gz: de3fb5ad387969bc8c796ca9db23de2f311e8b16f6002316456b475953d66ae1
3
+ metadata.gz: 10795ad02dbbf1ea2033af6b1b36857f0105acf45daa21f44bf576737b838331
4
+ data.tar.gz: e5fb0e9f651127a06d8057a5eeab6934ba62211c9bb9d3f0b8ac6df5e7e5bb58
5
5
  SHA512:
6
- metadata.gz: 175f49bcb07a4fd3fd313f5437b3d2b438a20d9a697e2cc481fcc7086a4a0add3e08fa342ed90f984fed13eff68bad632b8bd772bbbf6869319d1024ace9082d
7
- data.tar.gz: 8db9c02a65266fc858910ecf180800c4adabe0913eb02cb3464db665f51ad3ab3230a5bc1e6d38a581d93a874d390e6e8fa7ae7f72ec5c09d54cbecfcb070a71
6
+ metadata.gz: e738f18a2fe367d7796057fe2f098c6bc5f7291615e4315a78a33f0283df30b7c6c12b26af51b03489112ecd2c2310ac30a5bfac7d29e1c6be26a9700982dc41
7
+ data.tar.gz: 4ccb202176df05c3f9d4882ccd4abf6f025204ffa993b9daa6c3b3b4bcabc06eb22e4f98630253a85c1ef9ce68160b11d6beeb6c6a64ae8f7a885b26e12278ed
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,18 @@
1
+ = 3.6.11.1
2
+ - Fix required attribute broken on previous version when no validation was found
3
+
4
+ = 3.6.11
5
+ - Fix inplace edit cloning with jquery >= 1.9, when more than one child is cloned
6
+ - Support inplace edit cloning for :radio form_ui
7
+ - Add records parameter to cache_columns_count and related methods (count_query_for_column, mongoid_count_for_column)
8
+ - Fix required attribute when validator uses :on option, so on: :update only set required on update form, and :create only set required on create form
9
+
10
+ = 3.6.10
11
+ - Don't add numerical constraints based on conditional validation
12
+ - Fix typo in cache key for numerical constraints
13
+ - Fix duplicated params in search form, e.g. embedded constraints
14
+
15
+ = 3.6.9
1
16
  - Support depend on .rb or .json locale files for date picker bridge
2
17
  - Fix search with dates entered with timezone in datepicker
3
18
 
@@ -317,7 +317,6 @@ $.extend(InlineEditor.prototype, {
317
317
  if (editorNode.data('id')) editorNode.attr('id', editorNode.data('id') + this.settings.clone_id_suffix);
318
318
  editorNode.attr('name', 'inplace_value');
319
319
  editorNode.addClass('editor_field');
320
- this.setValue(editorNode, this.originalValue);
321
320
  clonedNodes = editorNode;
322
321
 
323
322
  if (patternNodes.additionalNodes) {
@@ -326,9 +325,10 @@ $.extend(InlineEditor.prototype, {
326
325
  if (patternNode.data('id')) {
327
326
  patternNode.attr('id', patternNode.data('id') + this.settings.clone_id_suffix);
328
327
  }
329
- clonedNodes = clonedNodes.after(patternNode);
328
+ clonedNodes.push(patternNode[0]);
330
329
  });
331
330
  }
331
+ this.setValue(clonedNodes, this.originalValue);
332
332
  return clonedNodes;
333
333
  },
334
334
 
@@ -349,23 +349,37 @@ $.extend(InlineEditor.prototype, {
349
349
  return nodes;
350
350
  },
351
351
 
352
- setValue: function(editField, textValue) {
353
- var function_name = 'setValueFor' + editField.get(0).nodeName.toLowerCase();
352
+ setValue: function(editFields, textValue) {
353
+ var editField = editFields.find(':input').addBack(':input'),
354
+ type = editField.get(0).nodeName.toLowerCase();
355
+ if (type === 'input') type = editField.attr('type').toLowerCase();
356
+ var function_name = 'setValueFor' + type;
354
357
  if (typeof(this[function_name]) == 'function') {
355
- this[function_name](editField, textValue);
358
+ this[function_name](editFields, textValue);
356
359
  } else {
357
360
  editField.val(textValue);
358
361
  }
359
362
  },
360
363
 
361
- setValueForselect: function(editField, textValue) {
362
- var option_value = editField.children("option:contains('" + textValue + "')").val();
364
+ setValueForselect: function(editFields, textValue) {
365
+ var editField = editFields.find('select').addBack('select').first(),
366
+ option_value = editField.children("option:contains('" + textValue + "')").val();
363
367
 
364
368
  if (typeof(option_value) !== 'undefined') {
365
369
  editField.val(option_value);
366
370
  }
367
371
  },
368
372
 
373
+ setValueForradio: function(editFields, textValue) {
374
+ var editField = editFields.find('input[type=radio]').addBack('input[type=radio]').filter(function() {
375
+ var contains = ':contains("' + textValue + '")';
376
+ return editFields.find('label[for="' + $(this).attr('id') + '"]' + contains).length ||
377
+ $(this).closest('label' + contains).length;
378
+ }).first();
379
+
380
+ if (editField.length) editField.prop('checked', true);
381
+ },
382
+
369
383
  inputNameAndClass: function() {
370
384
  return ' name="inplace_value" class="inplace_field" ';
371
385
  },
@@ -24,7 +24,7 @@
24
24
  <%= render_column(column, @record, renders_as, scope) %>
25
25
  <% end %>
26
26
  <% else -%>
27
- <li class="form-element <%= 'required' if column.required? %> <%= column.form_ui %> <%= column_css_class %>">
27
+ <li class="form-element <%= 'required' if column.required?(action_for_validation?(@record)) %> <%= column.form_ui %> <%= column_css_class %>">
28
28
  <%= render_column(column, @record, renders_as, scope, !authorized) %>
29
29
  </li>
30
30
  <% end -%>
@@ -4,7 +4,7 @@ if column.show_blank_record?(associated)
4
4
  show_blank_record = build_associated(column.association, parent_record)
5
5
  end
6
6
  disable_required_for_new = @disable_required_for_new
7
- @disable_required_for_new = !!show_blank_record unless (column.association.singular? && column.required?)
7
+ @disable_required_for_new = !!show_blank_record unless (column.association.singular? && column.required?(action_for_validation?(parent_record)))
8
8
  subform_div_id = "#{sub_form_id(:association => column.name, :id => parent_record.id || generated_id(parent_record) || 99999999999)}-div"
9
9
 
10
10
  # render footer before rendering associated records, fixes create new on self-associations
@@ -58,7 +58,7 @@
58
58
  end
59
59
 
60
60
  col_class = default_col_class.clone
61
- col_class << 'required' if column.required?
61
+ col_class << 'required' if column.required?(action_for_validation?(record))
62
62
  col_class << column.css_class unless column.css_class.nil? || column.css_class.is_a?(Proc)
63
63
  col_class << 'hidden' if column_renders_as(column) == :hidden
64
64
  -%>
@@ -88,7 +88,7 @@
88
88
  <% columns_group.each_column(for: record.class, crud_type: :read, flatten: true) do |col| %>
89
89
  <%
90
90
  col_class = default_col_class.clone
91
- col_class << 'required' if col.required?
91
+ col_class << 'required' if col.required?(action_for_validation?(record))
92
92
  col_class << col.css_class unless col.css_class.nil? || col.css_class.is_a?(Proc)
93
93
  col_class << 'hidden' if column_renders_as(col) == :hidden
94
94
  %>
@@ -14,7 +14,7 @@
14
14
  hidden_params = url_options.except(:controller, :action, :id, :search).to_query.split(Rack::Utils::DEFAULT_SEP)
15
15
  -%>
16
16
 
17
- <%= form_tag url_options, options do %>
17
+ <%= form_tag url_options.slice(:controller, :action, :id, :search), options do %>
18
18
  <% hidden_params.each do |pair| -%>
19
19
  <% key, value = pair.split('=', 2).map { |str| Rack::Utils.unescape(str) } -%>
20
20
  <%= hidden_field_tag(key, value) %>
@@ -125,7 +125,7 @@ module ActiveScaffold::Actions
125
125
  @remove_id_from_list_links = params[:id].blank?
126
126
  @page = current_page
127
127
  @records = @page.items
128
- cache_column_counts
128
+ cache_column_counts @records
129
129
  end
130
130
 
131
131
  def columns_to_cache_counts
@@ -136,12 +136,12 @@ module ActiveScaffold::Actions
136
136
  end
137
137
  end
138
138
 
139
- def cache_column_counts
139
+ def cache_column_counts(records)
140
140
  @counts = columns_to_cache_counts.each_with_object({}) do |column, counts|
141
141
  if ActiveScaffold::OrmChecks.active_record?(column.association.klass)
142
- counts[column.name] = count_query_for_column(column).count
142
+ counts[column.name] = count_query_for_column(column, records).count
143
143
  elsif ActiveScaffold::OrmChecks.mongoid?(column.association.klass)
144
- counts[column.name] = mongoid_count_for_column(column)
144
+ counts[column.name] = mongoid_count_for_column(column, records)
145
145
  end
146
146
  end
147
147
  end
@@ -151,17 +151,17 @@ module ActiveScaffold::Actions
151
151
  (!column.association.as || column.association.reverse_association)
152
152
  end
153
153
 
154
- def count_query_for_column(column)
154
+ def count_query_for_column(column, records)
155
155
  if count_on_association_class?(column)
156
- count_query_on_association_class(column)
156
+ count_query_on_association_class(column, records)
157
157
  else
158
- count_query_with_join(column)
158
+ count_query_with_join(column, records)
159
159
  end
160
160
  end
161
161
 
162
- def count_query_on_association_class(column)
162
+ def count_query_on_association_class(column, records)
163
163
  key = column.association.primary_key || :id
164
- query = column.association.klass.where(column.association.foreign_key => @records.map(&key.to_sym))
164
+ query = column.association.klass.where(column.association.foreign_key => records.map(&key.to_sym))
165
165
  if column.association.as
166
166
  query.where!(column.association.reverse_association.foreign_type => active_scaffold_config.model.name)
167
167
  end
@@ -171,17 +171,17 @@ module ActiveScaffold::Actions
171
171
  query.group(column.association.foreign_key)
172
172
  end
173
173
 
174
- def count_query_with_join(column)
174
+ def count_query_with_join(column, records)
175
175
  klass = column.association.klass
176
- query = active_scaffold_config.model.where(active_scaffold_config.primary_key => @records.map(&:id))
176
+ query = active_scaffold_config.model.where(active_scaffold_config.primary_key => records.map(&:id))
177
177
  .joins(column.name).group(active_scaffold_config.primary_key)
178
178
  .select("#{klass.quoted_table_name}.#{klass.quoted_primary_key}")
179
179
  query = query.uniq if column.association.scope && klass.instance_exec(&column.association.scope).values[:distinct]
180
180
  query
181
181
  end
182
182
 
183
- def mongoid_count_for_column(column)
184
- matches = {column.association.foreign_key => {'$in': @records.map(&:id)}}
183
+ def mongoid_count_for_column(column, records)
184
+ matches = {column.association.foreign_key => {'$in': records.map(&:id)}}
185
185
  if column.association.as
186
186
  matches[column.association.reverse_association.foreign_type] = {'$eq': active_scaffold_config.model.name}
187
187
  end
@@ -69,7 +69,7 @@ module ActiveScaffold::Actions
69
69
  @updated_record = @record
70
70
  # get_row so associations are cached like in list action
71
71
  # if record doesn't fullfil current conditions remove it from list
72
- @record = get_row
72
+ get_row
73
73
  rescue ActiveRecord::RecordNotFound
74
74
  nil
75
75
  end
@@ -66,8 +66,12 @@ module ActiveScaffold::DataStructures
66
66
  # whether the field is required or not. used on the form for visually indicating the fact to the user.
67
67
  # TODO: move into predicate
68
68
  attr_writer :required
69
- def required?
70
- @required
69
+ def required?(action = nil)
70
+ if action && @required
71
+ @required == true || @required.include?(action)
72
+ else
73
+ @required
74
+ end
71
75
  end
72
76
 
73
77
  attr_reader :update_columns
@@ -353,9 +357,11 @@ module ActiveScaffold::DataStructures
353
357
 
354
358
  # default all the configurable variables
355
359
  self.css_class = ''
356
- self.required = active_record_class.validators_on(name).any? do |val|
357
- validator_force_required?(val)
358
- end
360
+ validators_force_require_on = active_record_class.validators_on(name)
361
+ .map { |val| validator_force_required?(val) }
362
+ .select(&:present?)
363
+ self.required = validators_force_require_on.any? { |opt| opt == true } ||
364
+ validators_force_require_on.reject { |opt| opt == true }.flatten.presence
359
365
  self.sort = true
360
366
  self.search_sql = true
361
367
 
@@ -436,13 +442,18 @@ module ActiveScaffold::DataStructures
436
442
  return false if val.options[:if] || val.options[:unless]
437
443
  case val
438
444
  when ActiveModel::Validations::PresenceValidator
439
- true
445
+ validator_required_on(val)
440
446
  when ActiveModel::Validations::InclusionValidator
441
- !val.options[:allow_nil] && !val.options[:allow_blank] &&
442
- !inclusion_validator_for_checkbox?(val)
447
+ if !val.options[:allow_nil] && !val.options[:allow_blank] && !inclusion_validator_for_checkbox?(val)
448
+ validator_required_on(val)
449
+ end
443
450
  end
444
451
  end
445
452
 
453
+ def validator_required_on(val)
454
+ val.options[:on] ? Array(val.options[:on]) : true
455
+ end
456
+
446
457
  def inclusion_validator_for_checkbox?(val)
447
458
  @form_ui == :checkbox &&
448
459
  [[true, false], [false, true]].include?(val.options[:with] || val.options[:within] || val.options[:in])
@@ -55,7 +55,7 @@ module ActiveScaffold
55
55
  def active_scaffold_render_subform_column(column, scope, crud_type, readonly, add_class = false, record = nil) # rubocop:disable Metrics/ParameterLists
56
56
  if add_class
57
57
  col_class = []
58
- col_class << 'required' if column.required?
58
+ col_class << 'required' if column.required?(action_for_validation?(record))
59
59
  col_class << column.css_class unless column.css_class.nil? || column.css_class.is_a?(Proc)
60
60
  col_class << 'hidden' if column_renders_as(column) == :hidden
61
61
  col_class << 'checkbox' if column.form_ui == :checkbox
@@ -85,13 +85,17 @@ module ActiveScaffold
85
85
  options
86
86
  end
87
87
 
88
+ def action_for_validation?(record)
89
+ record&.persisted? ? :update : :create
90
+ end
91
+
88
92
  # the standard active scaffold options used for class, name and scope
89
93
  def active_scaffold_input_options(column, scope = nil, options = {})
90
94
  name = scope ? "record#{scope}[#{column.name}]" : "record[#{column.name}]"
91
95
  record = options[:object]
92
96
 
93
97
  # Add some HTML5 attributes for in-browser validation and better user experience
94
- if column.required? && (!@disable_required_for_new || scope.nil? || record&.persisted?)
98
+ if column.required?(action_for_validation?(record)) && (!@disable_required_for_new || scope.nil? || record&.persisted?)
95
99
  options[:required] = true
96
100
  end
97
101
  options[:placeholder] = column.placeholder if column.placeholder.present?
@@ -720,7 +724,9 @@ module ActiveScaffold
720
724
  # Try to get numerical constraints from model's validators
721
725
  def column_numerical_constraints(column, options)
722
726
  validators = column.active_record_class.validators.select do |v|
723
- v.is_a?(ActiveModel::Validations::NumericalityValidator) && v.attributes.include?(column.name)
727
+ v.is_a?(ActiveModel::Validations::NumericalityValidator) &&
728
+ v.attributes.include?(column.name) &&
729
+ !v.options[:if] && !v.options[:unless]
724
730
  end
725
731
 
726
732
  equal_validator = validators.find { |v| v.options[:equal_to] }
@@ -770,7 +776,7 @@ module ActiveScaffold
770
776
  end
771
777
 
772
778
  def numerical_constraints_for_column(column, options)
773
- constraints = Rails.cache.fetch("#{column.cache_key}#numerical_constarints") do
779
+ constraints = Rails.cache.fetch("#{column.cache_key}#numerical_constraints") do
774
780
  column_numerical_constraints(column, options)
775
781
  end
776
782
  constraints.merge(options)
@@ -2,7 +2,7 @@ module ActiveScaffold
2
2
  module Version
3
3
  MAJOR = 3
4
4
  MINOR = 6
5
- PATCH = 9
5
+ PATCH = '11.1'.freeze
6
6
 
7
7
  STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
8
  end
@@ -9,6 +9,16 @@ class ValidationReflectionTest < MiniTest::Test
9
9
  assert column.required?
10
10
  end
11
11
 
12
+ def test_set_required_for_validates_presence_of_with_on
13
+ column = ActiveScaffold::DataStructures::Column.new(:name, Company)
14
+ refute column.required?
15
+ Company.expects(:validators_on).with(:name).returns([ActiveModel::Validations::PresenceValidator.new(:attributes => :name, :on => [:create])])
16
+ column = ActiveScaffold::DataStructures::Column.new(:name, Company)
17
+ assert column.required?
18
+ assert column.required?(:create)
19
+ refute column.required?(:update)
20
+ end
21
+
12
22
  def test_set_required_for_validates_inclusion_of
13
23
  column = ActiveScaffold::DataStructures::Column.new(:name, Company)
14
24
  refute column.required?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_scaffold
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.9
4
+ version: 3.6.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Many, see README
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-03 00:00:00.000000000 Z
11
+ date: 2022-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -477,7 +477,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
477
477
  - !ruby/object:Gem::Version
478
478
  version: '0'
479
479
  requirements: []
480
- rubygems_version: 3.3.7
480
+ rubygems_version: 3.0.9
481
481
  signing_key:
482
482
  specification_version: 4
483
483
  summary: Rails 4.x and 5.x versions of ActiveScaffold supporting prototype and jquery