autoforme 1.11.0 → 1.13.0

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: '0198a23636933034920c066694a4acd8e58d5529fbf21ada5f542a7de444cc2c'
4
- data.tar.gz: 6cf1f310f06018a91573472c7410c1dda1842b7f96593a82deaf9be5f2bdd524
3
+ metadata.gz: 2bff68076c7cdf213c0142df9ab3809d33ede301c99f12e5cfbe7d1e111df30d
4
+ data.tar.gz: d2446bc814e6a19ebb70dfd46717ac596bb0aa4915abf02dd83aded973ba8d65
5
5
  SHA512:
6
- metadata.gz: 8931ddb513d806df30b8a4fe36fb20583597ac4e9f45e1144c5732cff66d09f92a14967a5ac4c35724ac339bfd23af866b454490ffabe99b327dfaff2e1aa787
7
- data.tar.gz: '097239f8074dc20537dec29064f24c2e5fbb521cf3586bb828726afc2b436eed190794d2b276e9b108c60bb6a4c3116a35dc651d54e32af5ff74d34e4a6b586e'
6
+ metadata.gz: '048c064a080ae50bd872be8e17a96f06e6f9eece5fb095c31121810edbe2f03d1f5db7a6562fb0d33c7229b1e1a49641246186f6567435664be646da836ce251'
7
+ data.tar.gz: 596b1caa6bfc6a91cf8745019df9c299e9315ace558388c9c5ba4fb44b7df18fdfd0aff0c9e5a7213c71e26ffb3fa12d3afed34e91c962e1ae258254413cded4
data/CHANGELOG CHANGED
@@ -1,3 +1,19 @@
1
+ === 1.13.0 (2024-07-10)
2
+
3
+ * Typecast primary key values before using them for lookup (jeremyevans)
4
+
5
+ * Support colon for model names to allow easier use of namespaced models (adam12) (#46)
6
+
7
+ === 1.12.0 (2022-06-29)
8
+
9
+ * Handle autocomplete queries with an empty query by returning empty string (jeremyevans)
10
+
11
+ * Switch autocomplete support to depend on Pixabay/JavaScript-autoComplete (jeremyevans)
12
+
13
+ * Make autoforme.js file no longer require JQuery (jeremyevans)
14
+
15
+ * Make navigation tab li tag use nav-item, for Bootstrap 5 compatibility (jeremyevans)
16
+
1
17
  === 1.11.0 (2021-11-30)
2
18
 
3
19
  * Require forme 2.0.0 (jeremyevans)
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013-2021 Jeremy Evans
1
+ Copyright (c) 2013-2024 Jeremy Evans
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to
data/README.rdoc CHANGED
@@ -6,12 +6,7 @@ integrate easily into web frameworks, and currently supports
6
6
  Roda, Sinatra, and Rails. The only currently supported ORM is
7
7
  Sequel::Model.
8
8
 
9
- AutoForme's UI and capabilities are modeled on
10
- scaffolding_extensions [2], though AutoForme is considerably more
11
- flexible in terms of configuration.
12
-
13
9
  1. https://github.com/jeremyevans/forme
14
- 2. https://github.com/jeremyevans/scaffolding_extensions
15
10
 
16
11
  = Installation
17
12
 
@@ -214,9 +209,12 @@ AutoForme also has javascript support for the progressive enhancement of the fol
214
209
  * Loading association links via ajax if lazy_load_association_links is true.
215
210
  * Adding and removing many-to-many associated objects via ajax for inline_mtm_associations
216
211
 
217
- AutoForme's javascript support is contained in the autoforme.js file in the root
218
- of the distribution. AutoForme's autocompleting support also requires
219
- https://github.com/dyve/jquery-autocomplete
212
+ AutoForme's javascript support is contained in the +autoforme.js+ file in the root
213
+ of the repository. AutoForme's autocompleting support also requires
214
+ https://github.com/Pixabay/JavaScript-autoComplete
215
+
216
+ Make sure to load the +autoforme.js+ file after the DOM content has been loaded, such
217
+ as at the end of the body.
220
218
 
221
219
  = Reloading Code
222
220
 
@@ -281,10 +279,10 @@ To handle multiple autoforme configurations, mounted at different subpaths:
281
279
  class App < Roda
282
280
  plugin :autoforme
283
281
 
284
- autoforme(name: 'artists')
282
+ autoforme(name: 'artists') do
285
283
  model Artist
286
284
  end
287
- autoforme(name: 'albums')
285
+ autoforme(name: 'albums') do
288
286
  model Album
289
287
  end
290
288
 
data/autoforme.js CHANGED
@@ -1,81 +1,122 @@
1
- var ready = function() {
2
- var autoforme = $('#autoforme_content');
3
- var base_url = autoforme.data('url');
1
+ (function() {
2
+ var autoforme = document.querySelector('#autoforme_content');
3
+ if (!autoforme) {
4
+ return;
5
+ }
6
+ var base_url = autoforme.getAttribute('data-url');
7
+ var xhr_headers = {'X-Requested-With': 'XMLHttpRequest'};
4
8
 
5
- function autoforme_fix_autocomplete(e) {
6
- $(e).find('.autoforme_autocomplete').each(function(){
7
- $(this).val($(this).val().split(' - ', 2)[0]);
9
+ function autoforme_fix_autocomplete(form) {
10
+ form.querySelectorAll('.autoforme_autocomplete').forEach((e) => {
11
+ e.value = e.value.split(' - ', 2)[0];
8
12
  });
9
13
  }
10
14
 
11
- function autoforme_setup_autocomplete() {
12
- autoforme.find('.autoforme_autocomplete').each(function(){
13
- var e = $(this);
14
- var column = e.data('column');
15
- var exclude = e.data('exclude');
15
+ function autoforme_setup_autocomplete(content) {
16
+ content.querySelectorAll('.autoforme_autocomplete').forEach((e) => {
17
+ var column = e.getAttribute('data-column');
18
+ var exclude = e.getAttribute('data-exclude');
16
19
  var url = base_url + 'autocomplete';
17
20
  if (column) {
18
21
  url += '/' + column;
19
22
  }
20
- url += '?type=' + e.data('type');
23
+ url += '?type=' + e.getAttribute('data-type');
21
24
  if (exclude) {
22
25
  url += '&exclude=' + exclude;
23
26
  }
24
- e.autocomplete(url);
27
+
28
+ new autoComplete({
29
+ selector: '[id="'+e.getAttribute("id")+'"]',
30
+ source: function(term, suggest) {
31
+ fetch((url + '&q=' + term), {headers: xhr_headers}).
32
+ then(function(response) {
33
+ return response.text();
34
+ }).
35
+ then(function(body) {
36
+ suggest(body.split("\n"));
37
+ });
38
+ }
39
+ });
25
40
  });
26
41
  }
27
42
 
28
- autoforme_setup_autocomplete();
43
+ autoforme_setup_autocomplete(autoforme);
29
44
 
30
- autoforme.on('submit', 'form', function(e){
31
- autoforme_fix_autocomplete(this);
45
+ autoforme.querySelectorAll("form").forEach((form) => {
46
+ form.addEventListener('submit', function(){
47
+ autoforme_fix_autocomplete(form);
48
+ }, {passive: true});
32
49
  });
33
50
 
51
+ var lazy_load_association_links = autoforme.querySelector('#lazy_load_association_links');
52
+ if (lazy_load_association_links) {
53
+ load_association_links = function(e) {
54
+ e.preventDefault();
55
+ lazy_load_association_links.removeEventListener('click', load_association_links);
34
56
 
35
- $('#lazy_load_association_links').click(function(e){
36
- var t = $(this);
37
- t.load(base_url + "association_links/" + t.data('object') + "?type=" + t.data('type'), autoforme_setup_autocomplete);
38
- t.unbind('click');
39
- e.preventDefault();
40
- });
57
+ var url = base_url + "association_links/" + load_association_links.getAttribute('data-object') + "?type=" + load_association_links.getAttribute('data-type');
58
+ fetch(url, {headers: xhr_headers}).
59
+ then(function(response) {
60
+ return response.text();
61
+ }).
62
+ then(function(body) {
63
+ lazy_load_association_links.innerHTML = body;
64
+ autoforme_setup_autocomplete(lazy_load_association_links);
65
+ });
66
+ };
67
+ lazy_load_association_links.addEventListener('click', load_association_links);
68
+ }
41
69
 
42
- autoforme.on('submit', '.mtm_add_associations', function(e){
43
- var form = $(this);
44
- if (form.find('.autoforme_autocomplete').length == 0) {
45
- var select = form.find('select')[0];
46
- $.post(this.action, form.serialize(), function(data, textStatus){
47
- $(select).find('option:selected').remove();
48
- select.selectedIndex = 0;
49
- $(form.data('remove')).append(data);
50
- });
51
- } else {
52
- autoforme_fix_autocomplete(form);
53
- $.post(this.action, form.serialize(), function(data, textStatus){
54
- var t = form.find('.autoforme_autocomplete');
55
- t.val('');
56
- t.data('autocompleter').cacheFlush();
57
- $(form.data('remove')).append(data);
70
+ setup_remove_hooks = function() {
71
+ autoforme.querySelectorAll('.inline_mtm_remove_associations form.mtm_remove_associations').forEach((form) => {
72
+ if (form.remove_hook_setup) {return;}
73
+ form.remove_hook_setup = true;
74
+
75
+ form.addEventListener('submit', function(e){
76
+ fetch(form.action, {method: 'post', body: new FormData(form), headers: xhr_headers}).
77
+ then(function(response) {
78
+ return response.text();
79
+ }).
80
+ then(function(body) {
81
+ document.querySelector(form.getAttribute('data-add')).insertAdjacentHTML('beforeend', body);
82
+ form.parentElement.remove();
83
+ });
84
+ e.preventDefault();
58
85
  });
59
- }
60
- e.preventDefault();
61
- });
86
+ });
87
+ };
88
+ setup_remove_hooks();
89
+
90
+ autoforme.querySelectorAll('.mtm_add_associations').forEach((form) => {
91
+ form.addEventListener('submit', function(e){
92
+ var form_ac = form.querySelector('.autoforme_autocomplete');
93
+ if (!form_ac) {
94
+ var select = form.querySelector('select');
62
95
 
63
- autoforme.on('submit', '.inline_mtm_remove_associations form', function(e){
64
- var form = $(this);
65
- var parent = form.parent();
66
- $.post(this.action, form.serialize(), function(data, textStatus){
67
- var t = $(form.data('add'));
68
- if (t[0].type == "text") {
69
- t.data('autocompleter').cacheFlush();
96
+ fetch(form.action, {method: 'post', body: new FormData(form), headers: xhr_headers}).
97
+ then(function(response) {
98
+ return response.text();
99
+ }).
100
+ then(function(body) {
101
+ select.remove(select.selectedIndex);
102
+ select.selectedIndex = 0;
103
+ document.querySelector(form.getAttribute('data-remove')).insertAdjacentHTML('beforeend', body);
104
+ setup_remove_hooks();
105
+ });
70
106
  } else {
71
- t.append(data);
107
+ autoforme_fix_autocomplete(form);
108
+
109
+ fetch(form.action, {method: 'post', body: new FormData(form), headers: xhr_headers}).
110
+ then(function(response) {
111
+ return response.text();
112
+ }).
113
+ then(function(body) {
114
+ form_ac.value = '';
115
+ document.querySelector(form.getAttribute('data-remove')).insertAdjacentHTML('beforeend', body);
116
+ setup_remove_hooks();
117
+ });
72
118
  }
73
- parent.remove();
119
+ e.preventDefault();
74
120
  });
75
- e.preventDefault();
76
121
  });
77
- };
78
-
79
-
80
- $(document).ready(ready);
81
- $(document).on('page:load', ready);
122
+ })();
@@ -87,9 +87,7 @@ module AutoForme
87
87
  else
88
88
  return false unless model.supported_action?(normalized_type, request)
89
89
 
90
- if title = TITLE_MAP[@normalized_type]
91
- @title = "#{model.class_name} - #{title}"
92
- end
90
+ @title = "#{model.class_name} - #{TITLE_MAP[@normalized_type]}"
93
91
  end
94
92
 
95
93
  true
@@ -134,7 +132,7 @@ module AutoForme
134
132
  type.to_s
135
133
  when :edit
136
134
  "edit/#{model.primary_key_value(obj)}"
137
- when :mtm_edit
135
+ else # when :mtm_edit
138
136
  "mtm_edit/#{model.primary_key_value(obj)}?association=#{params_association}"
139
137
  end
140
138
  path = url_for(path)
@@ -195,7 +193,7 @@ module AutoForme
195
193
  content << '<ul class="nav nav-tabs">'
196
194
  Model::DEFAULT_SUPPORTED_ACTIONS.each do |action_type|
197
195
  if model.supported_action?(action_type, request)
198
- content << "<li class=\"#{'active' if type == action_type}\"><a href=\"#{url_for(action_type)}\">#{tab_name(action_type)}</a></li>"
196
+ content << "<li class=\"nav-item #{'active' if type == action_type}\"><a class=\"nav-link\" href=\"#{url_for(action_type)}\">#{tab_name(action_type)}</a></li>"
199
197
  end
200
198
  end
201
199
  content << '</ul>'
@@ -315,19 +313,19 @@ module AutoForme
315
313
  if html = model.show_html_for(obj, column, type, request)
316
314
  col_opts = col_opts.merge(:html=>html)
317
315
  end
318
- t << f.input(column, col_opts).to_s
316
+ t << f.input(column, col_opts)
319
317
  end
320
318
  t << '</table>'
321
319
  if type == :show && model.supported_action?(:edit, request)
322
320
  t << Forme.form(form_attributes(:action=>url_for("edit/#{model.primary_key_value(obj)}")), form_opts) do |f1|
323
321
  f1.button(:value=>'Edit', :class=>'btn btn-primary')
324
- end.to_s
322
+ end
325
323
  end
326
324
  if type == :delete
327
325
  form_attr = form_attributes(:action=>url_for("destroy/#{model.primary_key_value(obj)}"), :method=>:post)
328
326
  t << Forme.form(form_attr, form_opts(form_attr[:action])) do |f1|
329
327
  f1.button(:value=>'Delete', :class=>'btn btn-danger')
330
- end.to_s
328
+ end
331
329
  else
332
330
  t << association_links(obj)
333
331
  end
@@ -358,11 +356,11 @@ module AutoForme
358
356
  f.input(column, col_opts)
359
357
  end
360
358
  f.button(:value=>'Update', :class=>'btn btn-primary')
361
- end.to_s
359
+ end
362
360
  if model.supported_action?(:delete, request)
363
361
  t << Forme.form(form_attributes(:action=>url_for("delete/#{model.primary_key_value(obj)}")), form_opts) do |f|
364
362
  f.button(:value=>'Delete', :class=>'btn btn-danger')
365
- end.to_s
363
+ end
366
364
  end
367
365
  t << association_links(obj)
368
366
  end
@@ -492,15 +490,15 @@ module AutoForme
492
490
  opts = model.column_options_for(:mtm_edit, request, assoc)
493
491
  add_opts = opts[:add] ? opts.merge(opts.delete(:add)) : opts
494
492
  remove_opts = opts[:remove] ? opts.merge(opts.delete(:remove)) : opts
495
- add_opts = {:name=>'add[]', :id=>'add', :label=>'Associate With'}.merge(add_opts)
493
+ add_opts = {:name=>'add[]', :id=>'add', :label=>'Associate With'}.merge!(add_opts)
496
494
  if model.association_autocomplete?(assoc, request)
497
- f.input(assoc, {:type=>'text', :class=>'autoforme_autocomplete', :attr=>{'data-type'=>'association', 'data-column'=>assoc, 'data-exclude'=>model.primary_key_value(obj)}, :value=>''}.merge(add_opts))
495
+ f.input(assoc, {:type=>'text', :class=>'autoforme_autocomplete', :attr=>{'data-type'=>'association', 'data-column'=>assoc, 'data-exclude'=>model.primary_key_value(obj)}, :value=>''}.merge!(add_opts))
498
496
  else
499
- f.input(assoc, {:dataset=>model.unassociated_mtm_objects(request, assoc, obj), :size=>10}.merge(add_opts))
497
+ f.input(assoc, {:dataset=>model.unassociated_mtm_objects(request, assoc, obj), :size=>10}.merge!(add_opts))
500
498
  end
501
- f.input(assoc, {:name=>'remove[]', :id=>'remove', :label=>'Disassociate From', :dataset=>model.associated_mtm_objects(request, assoc, obj), :value=>[], :size=>10}.merge(remove_opts))
499
+ f.input(assoc, {:name=>'remove[]', :id=>'remove', :label=>'Disassociate From', :dataset=>model.associated_mtm_objects(request, assoc, obj), :value=>[], :size=>10}.merge!(remove_opts))
502
500
  f.button(:value=>'Update', :class=>'btn btn-primary')
503
- end.to_s
501
+ end
504
502
  end
505
503
  else
506
504
  page do
@@ -545,7 +543,9 @@ module AutoForme
545
543
 
546
544
  # Handle autocomplete action by returning a string with one line per model object.
547
545
  def handle_autocomplete
548
- unless (query = request.params['q'].to_s).empty?
546
+ if (query = request.params['q'].to_s).empty?
547
+ ''
548
+ else
549
549
  model.autocomplete(:type=>@subtype, :request=>request, :association=>params_association, :query=>query, :exclude=>request.params['exclude']).join("\n")
550
550
  end
551
551
  end
@@ -653,14 +653,14 @@ module AutoForme
653
653
  t << Forme.form(obj, form_attr, form_opts(form_attr[:action])) do |f|
654
654
  opts = model.column_options_for(:mtm_edit, request, assoc)
655
655
  add_opts = opts[:add] ? opts.merge(opts.delete(:add)) : opts.dup
656
- add_opts = {:name=>'add[]', :id=>"add_#{assoc}"}.merge(add_opts)
656
+ add_opts = {:name=>'add[]', :id=>"add_#{assoc}"}.merge!(add_opts)
657
657
  if model.association_autocomplete?(assoc, request)
658
- f.input(assoc, {:type=>'text', :class=>'autoforme_autocomplete', :attr=>{'data-type'=>'association', 'data-column'=>assoc, 'data-exclude'=>model.primary_key_value(obj)}, :value=>''}.merge(add_opts))
658
+ f.input(assoc, {:type=>'text', :class=>'autoforme_autocomplete', :attr=>{'data-type'=>'association', 'data-column'=>assoc, 'data-exclude'=>model.primary_key_value(obj)}, :value=>''}.merge!(add_opts))
659
659
  else
660
- f.input(assoc, {:dataset=>model.unassociated_mtm_objects(request, assoc, obj), :multiple=>false, :add_blank=>true}.merge(add_opts))
660
+ f.input(assoc, {:dataset=>model.unassociated_mtm_objects(request, assoc, obj), :multiple=>false, :add_blank=>true}.merge!(add_opts))
661
661
  end
662
662
  f.button(:value=>'Add', :class=>'btn btn-xs btn-primary')
663
- end.to_s
663
+ end
664
664
  end
665
665
  t << "</div>"
666
666
  t << "<div class='inline_mtm_remove_associations'><ul>"
@@ -685,7 +685,7 @@ module AutoForme
685
685
  form_attr = form_attributes(:action=>url_for("mtm_update/#{model.primary_key_value(obj)}?association=#{assoc}&remove%5b%5d=#{model.primary_key_value(assoc_obj)}&redir=edit"), :method=>'post', :class => 'mtm_remove_associations', 'data-add'=>"#add_#{assoc}")
686
686
  t << Forme.form(form_attr, form_opts(form_attr[:action])) do |f|
687
687
  f.button(:value=>'Remove', :class=>'btn btn-xs btn-danger')
688
- end.to_s
688
+ end
689
689
  t << "</li>"
690
690
  end
691
691
  end
@@ -31,7 +31,11 @@ module AutoForme
31
31
  # Use Rails's form_authenticity_token for CSRF protection.
32
32
  def csrf_token_hash(action=nil)
33
33
  vc = @controller.view_context
34
- {vc.request_forgery_protection_token.to_s=>vc.form_authenticity_token} if vc.protect_against_forgery?
34
+ # :nocov:
35
+ if vc.protect_against_forgery?
36
+ # :nocov:
37
+ {vc.request_forgery_protection_token.to_s=>vc.form_authenticity_token}
38
+ end
35
39
  end
36
40
  end
37
41
 
@@ -23,7 +23,7 @@ module AutoForme
23
23
  # :nocov:
24
24
  end
25
25
 
26
- path_id = $1 if remaining_path =~ %r{\A\/([\w-]+)\z}
26
+ path_id = $1 if remaining_path =~ %r{\A\/([:\w-]+)\z}
27
27
  set_id(path_id)
28
28
  end
29
29
 
@@ -40,13 +40,13 @@ module AutoForme
40
40
  # Set the flash at notice level when redirecting, so it shows
41
41
  # up on the redirected page.
42
42
  def set_flash_notice(message)
43
- @controller.flash[flash_symbol_keys? ? :notice : 'notice'] = message
43
+ @controller.flash[flash_key(:notice)] = message
44
44
  end
45
45
 
46
46
  # Set the current flash at error level, used when displaying
47
47
  # pages when there is an error.
48
48
  def set_flash_now_error(message)
49
- @controller.flash.now[flash_symbol_keys? ? :error : 'error'] = message
49
+ @controller.flash.now[flash_key(:error)] = message
50
50
  end
51
51
 
52
52
  # Use Rack::Csrf for csrf protection if it is defined.
@@ -62,7 +62,7 @@ module AutoForme
62
62
  end
63
63
  {@controller.csrf_field=>token}
64
64
  # :nocov:
65
- elsif defined?(::Rack::Csrf)
65
+ elsif defined?(::Rack::Csrf) && !@controller.opts[:no_csrf]
66
66
  {::Rack::Csrf.field=>::Rack::Csrf.token(@env)}
67
67
  # :nocov:
68
68
  end
@@ -73,6 +73,12 @@ module AutoForme
73
73
  def flash_symbol_keys?
74
74
  !@controller.opts[:sessions_convert_symbols]
75
75
  end
76
+
77
+ def flash_key(key)
78
+ # :nocov:
79
+ flash_symbol_keys? ? key : key.to_s
80
+ # :nocov:
81
+ end
76
82
  end
77
83
 
78
84
  attr_reader :route_proc
@@ -30,7 +30,11 @@ module AutoForme
30
30
 
31
31
  # Use Rack::Csrf for csrf protection if it is defined.
32
32
  def csrf_token_hash(action=nil)
33
- {::Rack::Csrf.field=>::Rack::Csrf.token(@env)} if defined?(::Rack::Csrf)
33
+ # :nocov:
34
+ if defined?(::Rack::Csrf)
35
+ # :nocov:
36
+ {::Rack::Csrf.field=>::Rack::Csrf.token(@env)}
37
+ end
34
38
  end
35
39
  end
36
40
 
@@ -51,7 +55,6 @@ module AutoForme
51
55
  @autoforme_text
52
56
  else
53
57
  opts = framework.opts[:view_options]
54
- opts = opts ? opts.dup : {}
55
58
  erb("<%= @autoforme_text %>".dup, opts ? opts.dup : {})
56
59
  end
57
60
  else
@@ -60,11 +63,13 @@ module AutoForme
60
63
  end
61
64
 
62
65
  prefix = Regexp.escape(framework.prefix) if framework.prefix
66
+ # :nocov:
63
67
  if ::Sinatra::VERSION < '2'
64
68
  prefix = "\\A#{prefix}"
65
69
  suffix = "\\z"
66
70
  end
67
- regexp = %r{#{prefix}/([\w:]+)/(\w+)(?:/([\w-]+))?#{suffix}}
71
+ # :nocov:
72
+ regexp = %r{#{prefix}/([\w:]+)/(\w+)(?:/([:\w-]+))?#{suffix}}
68
73
  @controller.get regexp, &block
69
74
  @controller.post regexp, &block
70
75
  end
@@ -133,6 +133,12 @@ module AutoForme
133
133
 
134
134
  # Retrieve underlying model instance with matching primary key
135
135
  def with_pk(type, request, pk)
136
+ begin
137
+ pk = typecast_value(model.primary_key, pk)
138
+ rescue S::InvalidValue
139
+ raise S::NoMatchingRow
140
+ end
141
+
136
142
  dataset_for(type, request).with_pk!(pk)
137
143
  end
138
144
 
@@ -150,7 +156,7 @@ module AutoForme
150
156
  columns[i] = reflection[:name]
151
157
  end
152
158
  end
153
- columns.sort_by(&:to_s)
159
+ columns.sort!
154
160
  end
155
161
 
156
162
  # Add a filter restricting access to only rows where the column name
@@ -183,7 +189,7 @@ module AutoForme
183
189
  ds = ds.where(S.ilike(S.qualify(model.table_name, c), "%#{ds.escape_like(v)}%"))
184
190
  else
185
191
  begin
186
- typecasted_value = model.db.typecast_value(column_type(c), v)
192
+ typecasted_value = typecast_value(c, v)
187
193
  rescue S::InvalidValue
188
194
  ds = ds.where(false)
189
195
  break
@@ -355,6 +361,10 @@ module AutoForme
355
361
 
356
362
  private
357
363
 
364
+ def typecast_value(column, value)
365
+ model.db.typecast_value(column_type(column), value)
366
+ end
367
+
358
368
  def dataset_for(type, request)
359
369
  ds = model.dataset
360
370
  if filter = filter_for
@@ -6,7 +6,7 @@ module AutoForme
6
6
  MAJOR = 1
7
7
 
8
8
  # The minor version of AutoForme, updated for new feature releases of AutoForme.
9
- MINOR = 11
9
+ MINOR = 13
10
10
 
11
11
  # The patch version of AutoForme, updated only for bug fixes from the last
12
12
  # feature release.
@@ -6,7 +6,7 @@ class Roda
6
6
  module RodaPlugins
7
7
  module AutoForme
8
8
  # Require the render plugin, since it is required.
9
- def self.load_dependencies(app, opts={})
9
+ def self.load_dependencies(app, opts={}, &_)
10
10
  app.plugin :render
11
11
  end
12
12
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autoforme
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.0
4
+ version: 1.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-30 00:00:00.000000000 Z
11
+ date: 2024-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: forme
@@ -228,7 +228,6 @@ files:
228
228
  - CHANGELOG
229
229
  - MIT-LICENSE
230
230
  - README.rdoc
231
- - Rakefile
232
231
  - autoforme.js
233
232
  - lib/autoforme.rb
234
233
  - lib/autoforme/action.rb
@@ -243,17 +242,6 @@ files:
243
242
  - lib/autoforme/table.rb
244
243
  - lib/autoforme/version.rb
245
244
  - lib/roda/plugins/autoforme.rb
246
- - spec/all.rb
247
- - spec/associations_spec.rb
248
- - spec/basic_spec.rb
249
- - spec/mtm_spec.rb
250
- - spec/rails_spec_helper.rb
251
- - spec/roda_spec.rb
252
- - spec/roda_spec_helper.rb
253
- - spec/sequel_spec_helper.rb
254
- - spec/sinatra_spec_helper.rb
255
- - spec/spec_helper.rb
256
- - spec/unit_spec.rb
257
245
  homepage: http://github.com/jeremyevans/autoforme
258
246
  licenses:
259
247
  - MIT
@@ -263,7 +251,7 @@ metadata:
263
251
  documentation_uri: http://autoforme.jeremyevans.net
264
252
  mailing_list_uri: https://github.com/jeremyevans/autoforme/discussions
265
253
  source_code_uri: https://github.com/jeremyevans/autoforme
266
- post_install_message:
254
+ post_install_message:
267
255
  rdoc_options:
268
256
  - "--quiet"
269
257
  - "--line-numbers"
@@ -285,8 +273,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
285
273
  - !ruby/object:Gem::Version
286
274
  version: '0'
287
275
  requirements: []
288
- rubygems_version: 3.2.32
289
- signing_key:
276
+ rubygems_version: 3.5.11
277
+ signing_key:
290
278
  specification_version: 4
291
279
  summary: Web Administrative Console for Roda/Sinatra/Rails and Sequel::Model
292
280
  test_files: []