Class: AutoForme::Model

Inherits:
Object
  • Object
show all
Extended by:
OptsAttributes
Defined in:
lib/autoforme/model.rb

Overview

Wraps a specific model class

Direct Known Subclasses

AutoForme::Models::Sequel

Constant Summary collapse

AUTOCOMPLETE_TYPES =

Array of supported autocomplete types

[:show, :edit, :delete, :association, :mtm_edit].freeze
DEFAULT_LIMIT =

The default number of records to show on each browse/search results pages

25
DEFAULT_TABLE_CLASS =

The default table class to use for browse/search results pages

"table table-bordered table-striped"
DEFAULT_SUPPORTED_ACTIONS =

The default supported actions for models.

[:browse, :new, :show, :edit, :delete, :search, :mtm_edit]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from OptsAttributes

opts_attribute

Constructor Details

#initialize(model, framework) ⇒ Model

Returns a new instance of Model.



44
45
46
47
48
# File 'lib/autoforme/model.rb', line 44

def initialize(model, framework)
  @model = model
  @framework = framework
  @opts = {}
end

Instance Attribute Details

#frameworkObject (readonly)

The AutoForme::Framework class tied to the current model



27
28
29
# File 'lib/autoforme/model.rb', line 27

def framework
  @framework
end

#modelObject (readonly)

The underlying model class for the current model



30
31
32
# File 'lib/autoforme/model.rb', line 30

def model
  @model
end

#optsObject (readonly)

The options for the given model.



33
34
35
# File 'lib/autoforme/model.rb', line 33

def opts
  @opts
end

Class Method Details

.for(framework, type, model_class, &block) ⇒ Object

Create a new instance for the given model type and underlying model class tied to the given framework.



20
21
22
23
24
# File 'lib/autoforme/model.rb', line 20

def self.for(framework, type, model_class, &block)
  model = AutoForme.model_class_for(type).new(model_class, framework)
  model.instance_exec(&block) if block
  model
end

Instance Method Details

#associated_model_class(assoc) ⇒ Object

The AutoForme::Model instance associated to the given association.



225
226
227
# File 'lib/autoforme/model.rb', line 225

def associated_model_class(assoc)
  framework.model_classes[associated_class(assoc)]
end

#associated_object_display_name(assoc, request, obj) ⇒ Object

A human reable string for the associated object.



318
319
320
# File 'lib/autoforme/model.rb', line 318

def associated_object_display_name(assoc, request, obj)
  apply_name_method(column_options_for(:mtm_edit, request, assoc)[:name_method], obj, :mtm_edit, request)
end


183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/autoforme/model.rb', line 183

def association_links_for(type, request)
  case v = handle_proc(association_links || framework.association_links_for(model, type, request), type, request)
  when nil
    []
  when Array
    v
  when :all
    association_names
  when :all_except_mtm
    association_names - mtm_association_names
  else
    [v]
  end
end

#autocomplete_options_for(type, request) ⇒ Object



205
206
207
208
209
210
211
212
# File 'lib/autoforme/model.rb', line 205

def autocomplete_options_for(type, request)
  return unless AUTOCOMPLETE_TYPES.include?(type)
  framework_opts = framework.autocomplete_options_for(model, type, request)
  model_opts = handle_proc(autocomplete_options, type, request)
  if model_opts
    (framework_opts || {}).merge(model_opts)
  end
end

#before_action_hook(type, request) ⇒ Object

Run framework and model before_action hooks with type symbol and request.



255
256
257
258
259
260
261
262
# File 'lib/autoforme/model.rb', line 255

def before_action_hook(type, request)
  if v = framework.before_action
    v.call(type, request)
  end
  if v = before_action
    v.call(type, request)
  end
end

#class_nameObject

The name to display to the user for this model.



215
216
217
# File 'lib/autoforme/model.rb', line 215

def class_name
  class_display_name || model.name
end

#column_options_for(type, request, column) ⇒ Object

The options to use for the given column and request. Instead of the model options overriding the framework options, they are merged together.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/autoforme/model.rb', line 87

def column_options_for(type, request, column)
  framework_opts = case framework_opts = framework.column_options
  when Proc, Method
    framework_opts.call(model, column, type, request) || {}
  else
    extract_column_options(framework_opts, column, type, request)
  end

  model_opts = case model_opts = column_options
  when Proc, Method
    model_opts.call(column, type, request) || {}
  else
    extract_column_options(model_opts, column, type, request)
  end

  opts = framework_opts.merge(model_opts).dup

  if association?(column) && associated_model = associated_model_class(column)
    if associated_model.autocomplete_options_for(:association, request) && !opts[:as] && association_type(column) == :one
      opts[:type] = 'text'
      opts[:class] = 'autoforme_autocomplete'
      opts[:attr] = {'data-column'=>column, 'data-type'=>type}
      opts[:name] = form_param_name(column)
    else
      unless opts[:name_method]
        opts[:name_method] = lambda{|obj| associated_model.object_display_name(:association, request, obj)}
      end

      case type
      when :edit, :new, :search_form
        unless opts[:options] || opts[:dataset]
          opts[:dataset] = lambda{|ds| associated_model.apply_dataset_options(:association, request, ds)}
        end
      end
    end
  end

  case type
  when :show, :search_form
    opts[:required] = false unless opts.has_key?(:required)
    if type == :search_form && opts[:as] == :textarea
      opts.delete(:as)
    end
  end

  opts
end

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

The column value to display for the given object and column.



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/autoforme/model.rb', line 230

def column_value(type, request, obj, column)
  v = obj.send(column)
  return if v.nil?
  if association?(column) 
    opts = column_options_for(type, request, column) 
    case nm = opts[:name_method]
    when Symbol, String
      v = v.send(nm)
    when nil
    else
      v = nm.call(v)
    end
  end
  if v.is_a?(base_class)
    v = default_object_display_name(v)
  end
  v
end

#columns_for(type, request) ⇒ Object



81
82
83
# File 'lib/autoforme/model.rb', line 81

def columns_for(type, request)
  handle_proc(columns || framework.columns_for(model, type, request), type, request) || default_columns
end

#default_object_display_name(obj) ⇒ Object

A fallback for the display name for the object if none is configured.



323
324
325
326
327
328
329
330
331
# File 'lib/autoforme/model.rb', line 323

def default_object_display_name(obj)
  if obj.respond_to?(:forme_name)
    obj.forme_name
  elsif obj.respond_to?(:name)
    obj.name
  else
    primary_key_value(obj)
  end.to_s
end

#destroy(obj) ⇒ Object

Destroy the given object, deleting it from the database.



250
251
252
# File 'lib/autoforme/model.rb', line 250

def destroy(obj)
  obj.destroy
end

#display_name_forObject



179
180
181
# File 'lib/autoforme/model.rb', line 179

def display_name_for
  display_name || framework.display_name_for(model)
end

#eager_for(type, request) ⇒ Object



139
140
141
# File 'lib/autoforme/model.rb', line 139

def eager_for(type, request)
  handle_proc(eager, type, request)
end

#eager_graph_for(type, request) ⇒ Object



143
144
145
# File 'lib/autoforme/model.rb', line 143

def eager_graph_for(type, request)
  handle_proc(eager_graph, type, request)
end

#filter_forObject



147
148
149
# File 'lib/autoforme/model.rb', line 147

def filter_for
  filter || framework.filter_for(model)
end

#form_attributes_for(type, request) ⇒ Object



155
156
157
# File 'lib/autoforme/model.rb', line 155

def form_attributes_for(type, request)
  framework.form_attributes_for(model, type, request).merge(handle_proc(form_attributes, type, request) || {})
end

#form_options_for(type, request) ⇒ Object



159
160
161
# File 'lib/autoforme/model.rb', line 159

def form_options_for(type, request)
  framework.form_options_for(model, type, request).merge(handle_proc(form_options, type, request) || {})
end

#hook(type, request, obj) ⇒ Object

Run given hooks with the related object and request.



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

def hook(type, request, obj)
  if type.to_s =~ /before/
    if v = framework.send(type)
      v.call(obj, request)
    end
    if v = send(type)
      v.call(obj, request)
    end
  else
    if v = send(type)
      v.call(obj, request)
    end
    if v = framework.send(type)
      v.call(obj, request)
    end
  end
end

#inline_mtm_assocs(request) ⇒ Object

An array of many to many association symbols to handle inline on the edit forms.



77
78
79
# File 'lib/autoforme/model.rb', line 77

def inline_mtm_assocs(request)
  normalize_mtm_associations(handle_proc(inline_mtm_associations || framework.inline_mtm_associations_for(model, request), request))
end

#lazy_load_association_links?(type, request) ⇒ Boolean

Whether to lazy load association links for this model.

Returns:

  • (Boolean)


199
200
201
202
203
# File 'lib/autoforme/model.rb', line 199

def lazy_load_association_links?(type, request)
  v = handle_proc(lazy_load_association_links, type, request)
  v = framework.lazy_load_association_links?(model, type, request) if v.nil?
  v || false
end

#limit_for(type, request) ⇒ Object



175
176
177
# File 'lib/autoforme/model.rb', line 175

def limit_for(type, request)
  handle_proc(per_page || framework.limit_for(model, type, request), type, request) || DEFAULT_LIMIT
end

The name to use in links for this model. Also affects where this model is mounted at.



220
221
222
# File 'lib/autoforme/model.rb', line 220

def link
  link_name || class_name
end

#mtm_association_select_options(request) ⇒ Object

An array of many to many association symbols to handle via a separate mtm_edit page.



62
63
64
# File 'lib/autoforme/model.rb', line 62

def mtm_association_select_options(request)
  normalize_mtm_associations(handle_proc(mtm_associations || framework.mtm_associations_for(model, request), request))
end

#new(params, request) ⇒ Object

Create a new instance of the underlying model, setting defaults based on the params given.



285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/autoforme/model.rb', line 285

def new(params, request)
  obj = @model.new
  if params
    columns_for(:new, request).each do |col|
      if association?(col)
        col = association_key(col)
      end
      if v = params[col.to_s]
        obj.send("#{col}=", v)
      end
    end
  end
  obj
end

#object_display_name(type, request, obj) ⇒ Object

A human readable string representing the object.



313
314
315
# File 'lib/autoforme/model.rb', line 313

def object_display_name(type, request, obj)
  apply_name_method(display_name_for, obj, type, request).to_s
end

#order_for(type, request) ⇒ Object



135
136
137
# File 'lib/autoforme/model.rb', line 135

def order_for(type, request)
  handle_proc(order || framework.order_for(model, type, request), type, request)
end


163
164
165
# File 'lib/autoforme/model.rb', line 163

def page_footer_for(type, request)
  handle_proc(page_footer || framework.page_footer_for(model, type, request), type, request)
end

#page_header_for(type, request) ⇒ Object



167
168
169
# File 'lib/autoforme/model.rb', line 167

def page_header_for(type, request)
  handle_proc(page_header || framework.page_header_for(model, type, request), type, request)
end

#redirect_forObject



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

def redirect_for
  redirect || framework.redirect_for(model)
end

#select_options(type, request, opts = {}) ⇒ Object

An array of pairs for the select options to return for the given type.



301
302
303
304
305
306
307
308
309
310
# File 'lib/autoforme/model.rb', line 301

def select_options(type, request, opts={})
  case nm = opts[:name_method]
  when Symbol, String
    all_rows_for(type, request).map{|obj| [obj.send(nm), primary_key_value(obj)]}
  when nil
    all_rows_for(type, request).map{|obj| [object_display_name(type, request, obj), primary_key_value(obj)]}
  else
    all_rows_for(type, request).map{|obj| [nm.call(obj), primary_key_value(obj)]}
  end
end

#supported_action?(type, request) ⇒ Boolean

Whether the given type of action is supported for this model.

Returns:

  • (Boolean)


51
52
53
54
55
56
57
58
59
# File 'lib/autoforme/model.rb', line 51

def supported_action?(type, request)
  v = (handle_proc(supported_actions || framework.supported_actions_for(model, request), request) || DEFAULT_SUPPORTED_ACTIONS).include?(type)
  if v && type == :mtm_edit
    assocs = mtm_association_select_options(request)
    assocs && !assocs.empty?
  else
    v
  end
end

#supported_mtm_edit?(assoc, request) ⇒ Boolean

Whether an mtm_edit can be displayed for the given association

Returns:

  • (Boolean)


67
68
69
# File 'lib/autoforme/model.rb', line 67

def supported_mtm_edit?(assoc, request)
  mtm_association_select_options(request).map{|x| x.to_s}.include?(assoc)
end

#supported_mtm_update?(assoc, request) ⇒ Boolean

Whether an mtm_update can occur for the given association

Returns:

  • (Boolean)


72
73
74
# File 'lib/autoforme/model.rb', line 72

def supported_mtm_update?(assoc, request)
  supported_mtm_edit?(assoc, request) || inline_mtm_assocs(request).map{|x| x.to_s}.include?(assoc) 
end

#table_class_for(type, request) ⇒ Object



171
172
173
# File 'lib/autoforme/model.rb', line 171

def table_class_for(type, request)
  handle_proc(table_class || framework.table_class_for(model, type, request), type, request) || DEFAULT_TABLE_CLASS
end