Class: AutoForme::Action

Inherits:
Object
  • Object
show all
Defined in:
lib/autoforme/action.rb

Overview

Represents an action on a model in response to a web request.

Constant Summary collapse

ALL_SUPPORTED_ACTIONS =

Array of strings for all action types currently supported

%w'new create show edit update delete destroy browse search mtm_edit mtm_update association_links autocomplete'.freeze
NORMALIZED_ACTION_MAP =

Map of regular type symbols to normalized type symbols

{:create=>:new, :update=>:edit, :destroy=>:delete, :mtm_update=>:mtm_edit}
TITLE_MAP =

Map of type symbols to HTML titles

{:new=>'New', :show=>'Show', :edit=>'Edit', :delete=>'Delete', :browse=>'Browse', :search=>'Search', :mtm_edit=>'Many To Many Edit'}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, request) ⇒ Action

Creates a new action for the model and request. This action is not usable unless supported? is called first and it returns true.



34
35
36
37
# File 'lib/autoforme/action.rb', line 34

def initialize(model, request)
  @model = model
  @request = request
end

Instance Attribute Details

#modelObject (readonly)

The AutoForme::Model instance related to the current action



5
6
7
# File 'lib/autoforme/action.rb', line 5

def model
  @model
end

#normalized_typeObject (readonly)

The normalized type symbol related to the current action, so that paired actions such as new and create both use :new.



9
10
11
# File 'lib/autoforme/action.rb', line 9

def normalized_type
  @normalized_type
end

#params_associationObject (readonly)

An association symbol for the current related association.



12
13
14
# File 'lib/autoforme/action.rb', line 12

def params_association
  @params_association
end

#requestObject (readonly)

The AutoForme::Request instance related to the current action



15
16
17
# File 'lib/autoforme/action.rb', line 15

def request
  @request
end

#titleObject (readonly)

An string suitable for use as the HTML title on the displayed page



18
19
20
# File 'lib/autoforme/action.rb', line 18

def title
  @title
end

#typeObject (readonly)

The type symbols related to the current action (e.g. :new, :create).



21
22
23
# File 'lib/autoforme/action.rb', line 21

def type
  @type
end

Instance Method Details

If the framework contains the associated model class and that supports browsing, return a link to the associated browse page, otherwise, just return the name.



568
569
570
571
572
573
574
575
# File 'lib/autoforme/action.rb', line 568

def association_class_link(mc, assoc)
  assoc_name = humanize(assoc)
  if mc && mc.supported_action?(:browse, request)
    "<a href=\"#{base_url_for("#{mc.link}/browse")}\">#{assoc_name}</a>"
  else
    assoc_name
  end
end

For the given associated object, if the framework contains the associated model class, and that supports the type of action we are doing, return a link to the associated action page.



580
581
582
583
584
585
586
587
588
589
590
# File 'lib/autoforme/action.rb', line 580

def association_link(mc, assoc_obj)
  if mc
    t = mc.object_display_name(:association, request, assoc_obj)
    if mc.supported_action?(type, request)
      t = "<a href=\"#{base_url_for("#{mc.link}/#{type}/#{mc.primary_key_value(assoc_obj)}")}\">#{t}</a>"
    end
    t
  else
    model.default_object_display_name(assoc_obj)
  end
end

HTML fragment for the list of association links, allowing quick access to associated models and objects.



515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
# File 'lib/autoforme/action.rb', line 515

def association_link_list(obj)
  assocs = model.association_links_for(type, request) 
  return if assocs.empty?
  read_only = type == :show
  t = '<h3 class="associated_records_header">Associated Records</h3>'
  t << "<ul class='association_links'>\n"
  assocs.each do |assoc|
    mc = model.associated_model_class(assoc)
    t << "<li>"
    t << association_class_link(mc, assoc)
    t << "\n "

    case model.association_type(assoc)
    when :one
      if assoc_obj = obj.send(assoc)
        t << " - "
        t << association_link(mc, assoc_obj)
      end
      assoc_objs = []
    when :edit
      if !read_only && model.supported_mtm_edit?(assoc.to_s, request)
        t << "(<a href=\"#{url_for("mtm_edit/#{model.primary_key_value(obj)}?association=#{assoc}")}\">associate</a>)"
      end
      assoc_objs = obj.send(assoc)
    when :new
      if !read_only && mc && mc.supported_action?(:new, request)
        params = model.associated_new_column_values(obj, assoc).map do |col, value|
          "#{mc.link}%5b#{col}%5d=#{value}"
        end
        t << "(<a href=\"#{base_url_for("#{mc.link}/new?#{params.join('&amp;')}")}\">create</a>)"
      end
      assoc_objs = obj.send(assoc)
    else
      assoc_objs = []
    end

    unless assoc_objs.empty?
      t << "<ul>\n"
      assoc_objs.each do |assoc_obj|
        t << "<li>"
        t << association_link(mc, assoc_obj)
        t << "</li>"
      end
      t << "</ul>"
    end

    t << "</li>"
  end
  t << "</ul>"
end

HTML fragment containing the association links for the given object, or a link to lazily load them if configured. Also contains the inline mtm_edit forms when editing.



504
505
506
507
508
509
510
511
512
# File 'lib/autoforme/action.rb', line 504

def association_links(obj)
  if model.lazy_load_association_links?(type, request) && normalized_type != :association_links && request.params['associations'] != 'show'
    "<div id='lazy_load_association_links' data-object='#{model.primary_key_value(obj)}' data-type='#{type}'><a href=\"#{url_for("#{type}/#{model.primary_key_value(obj)}?associations=show")}\">Show Associations</a></div>"
  elsif type == :show
    association_link_list(obj).to_s
  else
    "#{inline_mtm_edit_forms(obj)}#{association_link_list(obj)}"
  end
end

#base_url_for(page) ⇒ Object

A path for the given page tied to the framework, but not the current model. Used for linking to other models in the same framework.



105
106
107
# File 'lib/autoforme/action.rb', line 105

def base_url_for(page)
  "#{request.path}#{model.framework.prefix}/#{page}"
end

#column_label_for(type, request, model, column) ⇒ Object

The label to use for the given column.



170
171
172
173
174
175
# File 'lib/autoforme/action.rb', line 170

def column_label_for(type, request, model, column)
  unless label = model.column_options_for(type, request, column)[:label]
    label = humanize(column)
  end
  label
end

#column_options_for(type, request, obj, column) ⇒ Object

The options to use for the given column, which will be passed to Forme::Form#input.



157
158
159
160
161
162
163
164
165
166
167
# File 'lib/autoforme/action.rb', line 157

def column_options_for(type, request, obj, column)
  opts = model.column_options_for(type, request, column)
  if opts[:class] == 'autoforme_autocomplete'
    if type == :show
      opts[:value] = model.column_value(type, request, obj, column)
    elsif key = obj.send(model.association_key(column))
      opts[:value] = "#{key} - #{model.column_value(type, request, obj, column)}"
    end
  end
  opts
end

#edit_page(obj) ⇒ Object

The page to use when editing the object.



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/autoforme/action.rb', line 317

def edit_page(obj)
  page do
    t = Forme.form(obj, form_attributes(:action=>url_for("update/#{model.primary_key_value(obj)}")), form_opts) do |f|
      model.columns_for(:edit, request).each do |column|
        f.input(column, column_options_for(:edit, request, obj, column))
      end
      f.button(:value=>'Update', :class=>'btn btn-primary')
    end.to_s
    if model.supported_action?(:delete, request)
      t << Forme.form(form_attributes(:action=>url_for("delete/#{model.primary_key_value(obj)}")), form_opts) do |f|
        f.button(:value=>'Delete', :class=>'btn btn-danger')
      end.to_s
    end
    t << association_links(obj)
  end
end

#form_attributes(attrs) ⇒ Object

Merge the model’s form attributes into the given form attributes, yielding the attributes to use for the form.



223
224
225
# File 'lib/autoforme/action.rb', line 223

def form_attributes(attrs)
  attrs.merge(model.form_attributes_for(type, request))
end

#form_optsObject

Options to use for the form. If the form uses POST, automatically adds the CSRF token.



212
213
214
215
216
217
218
219
# File 'lib/autoforme/action.rb', line 212

def form_opts
  opts = model.form_options_for(type, request).dup
  hidden_tags = opts[:hidden_tags] = []
  if csrf = request.csrf_token_hash
    hidden_tags << lambda{|tag| csrf if tag.attr[:method].to_s.upcase == 'POST'}
  end
  opts
end

#h(s) ⇒ Object

Convert input to a string adn HTML escape it.



88
89
90
# File 'lib/autoforme/action.rb', line 88

def h(s)
  Rack::Utils.escape_html(s.to_s)
end

#handleObject

Handle the current action, returning an HTML string containing the page content, or redirecting.



145
146
147
148
# File 'lib/autoforme/action.rb', line 145

def handle
  model.before_action_hook(type, request)
  send("handle_#{type}")
end

Handle association_links action by returning an HTML fragment of association links.



489
490
491
492
493
# File 'lib/autoforme/action.rb', line 489

def handle_association_links
  @type = @normalized_type = @subtype
  obj = model.with_pk(@type, request, request.id)
  association_links(obj)
end

#handle_autocompleteObject

Handle autocomplete action by returning a string with one line per model object.



496
497
498
499
500
# File 'lib/autoforme/action.rb', line 496

def handle_autocomplete
  unless (query = request.params['q'].to_s).empty?
    model.autocomplete(:type=>@subtype, :request=>request, :association=>params_association, :query=>query, :exclude=>request.params['exclude']).join("\n")
  end
end

#handle_browseObject

Handle browse action by showing a table containing model objects.



405
406
407
# File 'lib/autoforme/action.rb', line 405

def handle_browse
  table_page(*model.browse(type, request))
end

#handle_createObject

Handle the create action by creating a new model object.



247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/autoforme/action.rb', line 247

def handle_create
  obj = model.new(nil, request)
  model.set_fields(obj, :new, request, model_params)
  model.hook(:before_create, request, obj)
  if model.save(obj)
    model.hook(:after_create, request, obj)
    request.set_flash_notice("Created #{model.class_name}")
    redirect(:new, obj)
  else
    request.set_flash_now_error("Error Creating #{model.class_name}")
    new_page(obj)
  end
end

#handle_deleteObject

Handle the edit action by showing a list page if there is no model object selected, or a confirmation screen if there is one.



361
362
363
364
365
366
367
# File 'lib/autoforme/action.rb', line 361

def handle_delete
  if request.id
    handle_show
  else
    list_page(:delete, :form=>{:action=>url_for('delete')})
  end
end

#handle_destroyObject

Handle the destroy action by destroying the model object.



370
371
372
373
374
375
376
377
# File 'lib/autoforme/action.rb', line 370

def handle_destroy
  obj = model.with_pk(normalized_type, request, request.id)
  model.hook(:before_destroy, request, obj)
  model.destroy(obj)
  model.hook(:after_destroy, request, obj)
  request.set_flash_notice("Deleted #{model.class_name}")
  redirect(:delete, obj)
end

#handle_editObject

Handle the edit action by showing a list page if there is no model object selected, or the edit page if there is one.



335
336
337
338
339
340
341
342
343
# File 'lib/autoforme/action.rb', line 335

def handle_edit
  if request.id
    obj = model.with_pk(normalized_type, request, request.id)
    model.hook(:before_edit, request, obj)
    edit_page(obj)
  else
    list_page(:edit)
  end
end

#handle_mtm_editObject

Handle the mtm_edit action by showing a list page if there is no model object selected, a list of associations for that model if there is a model object but no association selected, or a mtm_edit form if there is a model object and association selected.



428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/autoforme/action.rb', line 428

def handle_mtm_edit
  if id = request.id
    obj = model.with_pk(:edit, request, request.id)
    unless assoc = params_association
      options = model.mtm_association_select_options(request)
      if options.length == 1
        assoc = options.first
      end
    end
    if assoc
      page do
        t = "<h2>Edit #{humanize(assoc)} for #{h model.object_display_name(type, request, obj)}</h2>"
        t << Forme.form(obj, form_attributes(:action=>url_for("mtm_update/#{model.primary_key_value(obj)}?association=#{assoc}")), form_opts) do |f|
          opts = model.column_options_for(:mtm_edit, request, assoc)
          add_opts = opts[:add] ? opts.merge(opts.delete(:add)) : opts
          remove_opts = opts[:remove] ? opts.merge(opts.delete(:remove)) : opts
          add_opts = {:name=>'add[]', :id=>'add', :label=>'Associate With'}.merge(add_opts)
          if model.association_autocomplete?(assoc, request)
            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))
          else
            f.input(assoc, {:dataset=>model.unassociated_mtm_objects(request, assoc, obj)}.merge(add_opts))
          end
          f.input(assoc, {:name=>'remove[]', :id=>'remove', :label=>'Disassociate From', :dataset=>model.associated_mtm_objects(request, assoc, obj), :value=>[]}.merge(remove_opts))
          f.button(:value=>'Update', :class=>'btn btn-primary')
        end.to_s
      end
    else
      page do
        Forme.form(form_attributes(:action=>"mtm_edit/#{model.primary_key_value(obj)}"), form_opts) do |f|
          f.input(:select, :options=>options, :name=>'association', :id=>'association', :label=>'Association', :add_blank=>true)
          f.button(:value=>'Edit', :class=>'btn btn-primary')
        end
      end
    end
  else
    list_page(:edit, :form=>{})
  end
end

#handle_mtm_updateObject

Handle mtm_update action by updating the related many to many association. For ajax requests, return an HTML fragment to update the page, otherwise redirect to the appropriate form.



469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
# File 'lib/autoforme/action.rb', line 469

def handle_mtm_update
  obj = model.with_pk(:edit, request, request.id)
  assoc = params_association
  assoc_obj = model.mtm_update(request, assoc, obj, request.params['add'], request.params['remove'])
  request.set_flash_notice("Updated #{assoc} association for #{model.class_name}") unless request.xhr?
  if request.xhr?
    if add = request.params['add']
      @type = :edit
      mtm_edit_remove(assoc, model.associated_model_class(assoc), obj, assoc_obj)
    else
      "<option value=\"#{model.primary_key_value(assoc_obj)}\">#{model.associated_object_display_name(assoc, request, assoc_obj)}</option>"
    end
  elsif request.params['redir'] == 'edit'
    redirect(:edit, obj)
  else
    redirect(:mtm_edit, obj)
  end
end

#handle_newObject

Handle the new action by always showing the new form.



240
241
242
243
244
# File 'lib/autoforme/action.rb', line 240

def handle_new
  obj = model.new(request.params[model.link], request)
  model.hook(:before_new, request, obj)
  new_page(obj)
end

#handle_searchObject

Handle browse action by showing a search form if no page is selected, or the correct page of search results if there is a page selected.



411
412
413
414
415
416
417
418
419
420
421
422
423
424
# File 'lib/autoforme/action.rb', line 411

def handle_search
  if request.id
    table_page(*model.search_results(normalized_type, request))
  else
    page do
      Forme.form(model.new(nil, request), form_attributes(:action=>url_for("search/1"), :method=>:get), form_opts) do |f|
        model.columns_for(:search_form, request).each do |column|
          f.input(column, column_options_for(:search_form, request, f.obj, column).merge(:name=>column, :id=>column))
        end
        f.button(:value=>'Search', :class=>'btn btn-primary')
      end
    end
  end
end

#handle_showObject

Handle the show action by showing a list page if there is no model object selected, or the show page if there is one.



308
309
310
311
312
313
314
# File 'lib/autoforme/action.rb', line 308

def handle_show
  if request.id
    show_page(model.with_pk(normalized_type, request, request.id))
  else
    list_page(:show)
  end
end

#handle_updateObject

Handle the update action by updating the current model object.



346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'lib/autoforme/action.rb', line 346

def handle_update
  obj = model.with_pk(normalized_type, request, request.id)
  model.set_fields(obj, :edit, request, model_params)
  model.hook(:before_update, request, obj)
  if model.save(obj)
    model.hook(:after_update, request, obj)
    request.set_flash_notice("Updated #{model.class_name}")
    redirect(:edit, obj)
  else
    request.set_flash_now_error("Error Updating #{model.class_name}")
    edit_page(obj)
  end
end

#humanize(string) ⇒ Object

Convert the given object into a suitable human readable string.



151
152
153
154
# File 'lib/autoforme/action.rb', line 151

def humanize(string)
  string = string.to_s
  string.respond_to?(:humanize) ? string.humanize : string.gsub(/_/, " ").capitalize
end

#idempotent?Boolean

Return whether the current action is an idempotent action.

Returns:

  • (Boolean)


93
94
95
# File 'lib/autoforme/action.rb', line 93

def idempotent?
  type == normalized_type
end

#inline_mtm_edit_forms(obj) ⇒ Object

HTML fragment used for the inline mtm_edit forms on the edit page.



593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
# File 'lib/autoforme/action.rb', line 593

def inline_mtm_edit_forms(obj)
  assocs = model.inline_mtm_assocs(request)
  return if assocs.empty?

  t = "<div class='inline_mtm_add_associations'>"
  assocs.each do |assoc|
    form_attr = form_attributes(:action=>url_for("mtm_update/#{model.primary_key_value(obj)}?association=#{assoc}&redir=edit"), :class => 'mtm_add_associations', 'data-remove' => "##{assoc}_remove_list")
    t << Forme.form(obj, form_attr, form_opts) do |f|
      opts = model.column_options_for(:mtm_edit, request, assoc)
      add_opts = opts[:add] ? opts.merge(opts.delete(:add)) : opts.dup
      add_opts = {:name=>'add[]', :id=>"add_#{assoc}"}.merge(add_opts)
      if model.association_autocomplete?(assoc, request)
        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))
      else
        f.input(assoc, {:dataset=>model.unassociated_mtm_objects(request, assoc, obj), :multiple=>false, :add_blank=>true}.merge(add_opts))
      end
      f.button(:value=>'Add', :class=>'btn btn-mini btn-primary')
    end.to_s
  end
  t << "</div>"
  t << "<div class='inline_mtm_remove_associations'><ul>"
  assocs.each do |assoc|
    mc = model.associated_model_class(assoc)
    t << "<li>"
    t << association_class_link(mc, assoc)
    t << "<ul id='#{assoc}_remove_list'>"
    obj.send(assoc).each do |assoc_obj|
      t << mtm_edit_remove(assoc, mc, obj, assoc_obj)
    end
    t << "</ul></li>"
  end
  t << "</ul></div>"
end

#list_page(type, opts = {}) ⇒ Object

Shared page used by show, edit, and delete actions that shows a list of available model objects (or an autocompleting box), and allows the user to choose one to act on.



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/autoforme/action.rb', line 263

def list_page(type, opts={})
  page do
    form_attr = form_attributes(opts[:form] || {:action=>url_for(type)})
    Forme.form(form_attr, form_opts) do |f|
      input_opts = {:name=>'id', :id=>'id', :label=>model.class_name}
      if model.autocomplete_options_for(type, request)
        input_type = :text
        input_opts.merge!(:class=>'autoforme_autocomplete', :attr=>{'data-type'=>type})
      else
        input_type = :select
        input_opts.merge!(:options=>model.select_options(type, request), :add_blank=>true)
      end
      f.input(input_type, input_opts)
      f.button(:value=>type.to_s.capitalize, :class=>"btn btn-#{type == :delete ? 'danger' : 'primary'}")
    end
  end
end

#model_paramsObject

Get request parameters for the model. Used when retrieving form values that use namespacing.



99
100
101
# File 'lib/autoforme/action.rb', line 99

def model_params
  request.params[model.params_name]
end

#mtm_edit_remove(assoc, mc, obj, assoc_obj) ⇒ Object

Line item containing form to remove the currently associated object.



628
629
630
631
632
633
634
635
636
# File 'lib/autoforme/action.rb', line 628

def mtm_edit_remove(assoc, mc, obj, assoc_obj)
  t = "<li>"
  t << association_link(mc, assoc_obj)
  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}")
  t << Forme.form(form_attr, form_opts) do |f|
    f.button(:value=>'Remove', :class=>'btn btn-mini btn-danger')
  end.to_s
  t << "</li>"
end

#new_page(obj, opts = {}) ⇒ Object

HTML content used for the new action



228
229
230
231
232
233
234
235
236
237
# File 'lib/autoforme/action.rb', line 228

def new_page(obj, opts={})
  page do
    Forme.form(obj, form_attributes(:action=>url_for("create")), form_opts) do |f|
      model.columns_for(:new, request).each do |column|
        f.input(column, column_options_for(:new, request, obj, column))
      end
      f.button(:value=>'Create', :class=>'btn btn-primary')
    end
  end
end

#pageObject

Yields and wraps the returned data in a header and footer for the page.



201
202
203
204
205
206
207
208
209
# File 'lib/autoforme/action.rb', line 201

def page
  html = ''
  html << (model.page_header_for(type, request) || tabs)
  html << "<div id='autoforme_content' data-url='#{url_for('')}'>"
  html << yield.to_s
  html << "</div>"
  html << model.page_footer_for(type, request).to_s
  html
end

#redirect(type, obj) ⇒ Object

Redirect to a page based on the type of action and the given object.



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/autoforme/action.rb', line 120

def redirect(type, obj)
  if redir = model.redirect_for
    path = redir.call(obj, type, request)
  end

  unless path
    path = case type
    when :new, :delete
      type.to_s
    when :edit
      "edit/#{model.primary_key_value(obj)}"
    when :mtm_edit
      "mtm_edit/#{model.primary_key_value(obj)}?association=#{params_association}"
    else
      raise Error, "Unhandled redirect type: #{type.inspect}"
    end
    path = url_for(path)
  end

  request.redirect(path)
  nil
end

#show_page(obj) ⇒ Object

The page to use when displaying an object, always used as a confirmation screen when deleting an object.



282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/autoforme/action.rb', line 282

def show_page(obj)
  page do
    t = ''
    f = Forme::Form.new(obj, :formatter=>:readonly, :wrapper=>:trtd)
    t << "<table class=\"#{model.table_class_for(:show, request)}\">"
    model.columns_for(type, request).each do |column|
      t << f.input(column, column_options_for(:show, request, obj, column)).to_s
    end
    t << '</table>'
    if type == :show && model.supported_action?(:edit, request)
      t << Forme.form(form_attributes(:action=>url_for("edit/#{model.primary_key_value(obj)}")), form_opts) do |f|
        f.button(:value=>'Edit', :class=>'btn btn-primary')
      end.to_s
    end
    if type == :delete
      t << Forme.form(form_attributes(:action=>url_for("destroy/#{model.primary_key_value(obj)}"), :method=>:post), form_opts) do |f|
        f.button(:value=>'Delete', :class=>'btn btn-danger')
      end.to_s
    else
      t << association_links(obj)
    end
    t
  end
end

#subtypeObject

The subtype of request, used for association_links and autocomplete actions.



115
116
117
# File 'lib/autoforme/action.rb', line 115

def subtype
  ((t = request.params['type']) && ALL_SUPPORTED_ACTIONS.include?(t) && t.to_sym) || :edit
end

#supported?Boolean

Return true if the action is supported, and false otherwise. An action may not be supported if the type is not one of the supported types, or if an non-idemponent request is issued with get instead of post, or potentionally other reasons.

As a side-effect, this sets up additional state related to the request.

Returns:

  • (Boolean)


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/autoforme/action.rb', line 45

def supported?
  return false unless idempotent? || request.post?
  return false unless ALL_SUPPORTED_ACTIONS.include?(request.action_type)

  @type = request.action_type.to_sym
  @normalized_type = NORMALIZED_ACTION_MAP.fetch(@type, @type)

  case type
  when :mtm_edit
    return false unless model.supported_action?(type, request)
    if request.id && (assoc = request.params['association'])
      return false unless model.supported_mtm_edit?(assoc, request)
      @params_association = assoc.to_sym
    end

    @title = "#{model.class_name} - #{TITLE_MAP[type]}"
  when :mtm_update
    return false unless request.id && (assoc = request.params['association']) && model.supported_mtm_update?(assoc, request)
    @params_association = assoc.to_sym
  when :association_links
    @subtype = subtype
    return false unless model.supported_action?(@subtype, request)
  when :autocomplete
    if assoc = request.id
      return false unless model.association?(assoc)
      @params_association = assoc.to_sym
      @subtype = :association
    else
      @subtype = subtype
    end
    return false unless model.autocomplete_options_for(@subtype, request)
  else
    return false unless model.supported_action?(normalized_type, request)

    if title = TITLE_MAP[type]
      @title = "#{model.class_name} - #{title}"
    end
  end

  true
end

#tab_name(type) ⇒ Object

The name to give the tab for the given type.



189
190
191
192
193
194
195
196
197
198
# File 'lib/autoforme/action.rb', line 189

def tab_name(type)
  case type
  when :browse
    model.class_name
  when :mtm_edit
    'MTM'
  else
    type.to_s.capitalize
  end
end

#table_page(next_page, objs) ⇒ Object

Show page used for browse/search pages.



398
399
400
401
402
# File 'lib/autoforme/action.rb', line 398

def table_page(next_page, objs)
  page do
    Table.new(self, objs).to_s << table_pager(normalized_type, next_page)
  end
end

#table_pager(type, next_page) ⇒ Object

HTML fragment for the table pager, showing links to next page or previous page for browse/search forms.



380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
# File 'lib/autoforme/action.rb', line 380

def table_pager(type, next_page)
  html = '<ul class="pager">'
  page = request.id.to_i
  if page > 1
    html << "<li><a href=\"#{url_for("#{type}/#{page-1}?#{h request.query_string}")}\">Previous</a></li>"
  else
    html << '<li class="disabled"><a href="#">Previous</a></li>'
  end
  if next_page
    page = 1 if page < 1
    html << "<li><a href=\"#{url_for("#{type}/#{page+1}?#{h request.query_string}")}\">Next</a></li>"
  else
    html << '<li class="disabled"><a href="#">Next</a></li>'
  end
  html << "</ul>"
end

#tabsObject

HTML fragment for the default page header, which uses tabs for each supported action.



178
179
180
181
182
183
184
185
186
# File 'lib/autoforme/action.rb', line 178

def tabs
  content = '<ul class="nav nav-tabs">'
  Model::DEFAULT_SUPPORTED_ACTIONS.each do |action_type|
    if model.supported_action?(action_type, request)
      content << "<li class=\"#{'active' if type == action_type}\"><a href=\"#{url_for(action_type)}\">#{tab_name(action_type)}</a></li>"
    end
  end
  content << '</ul>'
end

#url_for(page) ⇒ Object

A path for the given page for the same model.



110
111
112
# File 'lib/autoforme/action.rb', line 110

def url_for(page)
  base_url_for("#{model.link}/#{page}")
end