Module: ScaffoldingExtensions::MetaModel

Included in:
ActiveRecord::Base, Sequel::Model
Defined in:
lib/scaffolding_extensions/meta_model.rb

Overview

Class methods shared by all models

Many class methods can be overridden for particular use cases by setting other methods or instance variables. For example, scaffold_fields is a method that takes an action, such as :new. scaffold_fields(:new) will first check if scaffold_new_fields is a method, and will call it if so. If not, it will check if @scaffold_new_fields is defined, and use it if so. If not, will take the default course of action.

The first argument to the overridable method is used to search for the override method or instance variable. If a override method is used, the remaining arguments to the overridable method will be passed to it. Otherwise, the default method will be used.

For example, scaffold_find_object(action, id, options) is an overridable method. That means if :delete is the action, it will first look for scaffold_delete_find_object, and if it exists it will call scaffold_delete_find_object(id, options).

If a method can be overridden by an instance variable, it should have only one argument.

The methods that are overridable by other methods are (without the “scaffold_” prefix): add_associated_objects, associated_objects, association_find_object, association_find_objects, find_object, find_objects, new_associated_object_values, remove_associated_objects, save, unassociated_objects, and filter_attributes.

The methods that are overridable by other methods or instance variables are (again, without the “scaffold_” prefix): associated_human_name, association_use_auto_complete, fields, include, select_order, attributes, include_association, and select_order_association.

Most methods that find objects check options[scaffold_session_value] as a security check if scaffold_session_value is set.

There are some methods that are so similar that they are dynamically defined using define_method. They are:

  • scaffold_association_list_class: The html class attribute of the association list

  • scaffold_habtm_with_ajax: Whether to use Ajax when scaffolding habtm associations for this model

  • scaffold_load_associations_with_ajax: Whether to use Ajax when loading associations on the edit page

  • scaffold_browse_records_per_page: The number of records to show on each page when using the browse scaffold

  • scaffold_convert_text_to_string: Whether to use input of type text instead of a text area for columns of type :text

  • scaffold_search_results_limit: The maximum number of results to show on the scaffolded search results page

Each of these methods can be set with an instance variable. If the instance variable is not set, it will use the default value from SCAFFOLD_OPTIONS.

Constant Summary collapse

SCAFFOLD_OPTIONS =

Sets the default options for all models, which can be overriden by class instance variables (iv):

  • :text_to_string: If true, by default, use input type text instead of textarea for fields of type text (iv: @scaffold_convert_text_to_string)

  • :table_classes: Set the default table classes for different scaffolded HTML tables (iv: @scaffold_table_classes)

  • :column_type_options: Override the default options for a given column type (iv: @scaffold_column_type_options)

  • :column_types: Override the default column type for a given attribute (iv: @scaffold_column_types)

  • :column_options: Override the default column options for a given attribute (iv: @scaffold_column_options_hash)

  • :column_names: Override the visible names of columns for each attribute (iv: @scaffold_column_names)

  • :association_list_class: Override the html class for the association list in the edit view (iv: @scaffold_association_list_class)

  • :browse_limit: The default number of records per page to show in the browse scaffold. If nil, the search results will be displayed on one page instead of being paginated (iv: @scaffold_browse_records_per_page)

  • :search_limit: The default limit on scaffolded search results. If nil, the search results will be displayed on one page instead of being paginated (iv: @scaffold_search_results_limit)

  • :habtm_ajax: Whether or not to use Ajax (instead of a separate page) for modifying habtm associations (iv: @scaffold_habtm_with_ajax)

  • :load_associations_ajax - Whether or not to use Ajax to load the display of associations on the edit page, useful if the default display is too slow (iv: @scaffold_load_associations_with_ajax)

  • :auto_complete: Hash containing the default options to use for the scaffold autocompleter (iv: @scaffold_auto_complete_options)

{:text_to_string=>false, 
  :table_classes=>{:form=>'table formtable', :list=>'table table-condensed table-striped sortable', :show=>'table sortable'},
  :column_type_options=>{},
  :column_types=>{},
  :column_options=>{},
  :association_list_class=>''.freeze,
  :column_names=>{},
  :browse_limit=>10,
  :search_limit=>10,
  :habtm_ajax=>false,
  :load_associations_ajax=>false,
  :auto_complete=>{:enable=>false, :sql_name=>'LOWER(name)', :format_string=>:substring, 
    :search_operator=>'LIKE', :results_limit=>10, :phrase_modifier=>:downcase},
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#scaffold_field_wrapperObject (readonly)

Override the typical table-based form display by overriding these wrappers. Should return a proc that takes an html label and widget and returns an html fragment.



114
115
116
# File 'lib/scaffolding_extensions/meta_model.rb', line 114

def scaffold_field_wrapper
  @scaffold_field_wrapper
end

#scaffold_form_wrapperObject (readonly)

Override the typical table-based form display by overriding these wrappers. Should return a proc that takes rows returned by scaffold_field_wrapper and returns an html fragment.



119
120
121
# File 'lib/scaffolding_extensions/meta_model.rb', line 119

def scaffold_form_wrapper
  @scaffold_form_wrapper
end

#scaffold_session_valueObject (readonly)

Control access to objects of this model via a session value. For example if set to :user_id, would only show objects with the same user_id as session, and would not allow access to any objects that didn’t have a matching user_id.



109
110
111
# File 'lib/scaffolding_extensions/meta_model.rb', line 109

def scaffold_session_value
  @scaffold_session_value
end

Instance Method Details

#scaffold_add_associated_objects(association, object, options, *associated_object_ids) ⇒ Object

Add the objects specified by associated_object_ids to the given object using the given association. If the object to be associated with the given object is already associated with it, skip it (don’t try to associate it multiple times). Returns the associated object (if only one id was given), or an array of objects (if multiple ids were given).



126
127
128
129
130
131
132
133
134
# File 'lib/scaffolding_extensions/meta_model.rb', line 126

def scaffold_add_associated_objects(association, object, options, *associated_object_ids)
  unless associated_object_ids.empty?
    scaffold_transaction do
      associated_objects = associated_object_ids.map{|i| scaffold_association_find_object(association, i.to_i, :session=>options[:session])}
      associated_objects.each{|o| scaffold_add_associated_object(association, object, o)}
      associated_object_ids.length == 1 ? associated_objects.first : associated_objects
    end
  end
end

#scaffold_associated_human_name(association) ⇒ Object

Return the human name for the given association, defaulting to humanizing the association name



138
139
140
# File 'lib/scaffolding_extensions/meta_model.rb', line 138

def scaffold_associated_human_name(association)
  association.to_s.humanize
end

#scaffold_associated_name(association) ⇒ Object

The scaffold_name of the associated class. Not overridable, as that allows for the possibility of broken links.



144
145
146
# File 'lib/scaffolding_extensions/meta_model.rb', line 144

def scaffold_associated_name(association)
  scaffold_associated_class(association).scaffold_name
end

#scaffold_associated_objects(association, object, options) ⇒ Object

All objects that are currently associated with the given object. This method does not check that the returned associated objects meet the associated class’s scaffold_session_value constraint, as it is assumed that all objects currently assocated with the given object have already met the criteria. If that is not the case, you should override this method.



152
153
154
# File 'lib/scaffolding_extensions/meta_model.rb', line 152

def scaffold_associated_objects(association, object, options)
  object.send(association)
end

#scaffold_association_find_object(association, id, options) ⇒ Object

Finds a given object in the associated class that has the matching id.



157
158
159
# File 'lib/scaffolding_extensions/meta_model.rb', line 157

def scaffold_association_find_object(association, id, options)
  scaffold_associated_class(association).scaffold_find_object(:associated, id, options)
end

#scaffold_association_find_objects(association, options) ⇒ Object

Find all objects of the associated class. Does not use any conditions of the association (they are can’t be used reliably, since they require an object to interpolate them), so if there are special conditions on the association, you’ll want to override this method.



164
165
166
167
# File 'lib/scaffolding_extensions/meta_model.rb', line 164

def scaffold_association_find_objects(association, options)
  klass = scaffold_associated_class(association)
  klass.scaffold_get_objects(:order=>scaffold_select_order_association(association), :include=>scaffold_include_association(association), :conditions=>klass.scaffold_session_conditions(options[:session]))
end

#scaffold_association_use_auto_complete(association) ⇒ Object

Whether to use autocompleting for linked associations. Defaults to whether the associated class uses auto completing. Always false if scaffold_association_find_objects is overridden for the specific association.



172
173
174
# File 'lib/scaffolding_extensions/meta_model.rb', line 172

def scaffold_association_use_auto_complete(association)
  scaffold_associated_class(association).scaffold_use_auto_complete && !respond_to?("scaffold_#{association}_association_find_objects")
end

#scaffold_auto_complete_associationsObject

Defaults to associations specified by scaffold fields that are autocompleting. Can be set with an instance variable.



177
178
179
# File 'lib/scaffolding_extensions/meta_model.rb', line 177

def scaffold_auto_complete_associations
  @scaffold_auto_complete_associations ||= scaffold_fields(:edit).reject{|field| !(scaffold_association(field) && scaffold_association_use_auto_complete(field))}
end

#scaffold_auto_complete_find(phrase, options = {}) ⇒ Object

Return all records that match the given phrase (usually a substring of the most important column). If options is present, delegate to the associated class’s scaffold_auto_complete_find.

Allows method override (options.delete(:association))



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/scaffolding_extensions/meta_model.rb', line 186

def scaffold_auto_complete_find(phrase, options = {})
  session = options.delete(:session)
  if association = options.delete(:association)
    if meth = scaffold_method_override(:auto_complete_find, association, phrase, options)
      meth.call
    else
      scaffold_associated_class(association).scaffold_auto_complete_find(phrase, :session=>session)
    end
  else
    find_options = { :limit => scaffold_auto_complete_results_limit,
        :conditions => [scaffold_auto_complete_conditions(phrase), scaffold_session_conditions(session)],
        :order => scaffold_select_order(:auto_complete),
        :include => scaffold_include(:auto_complete)}.merge(options)
    scaffold_get_objects(find_options)
  end
end

#scaffold_browse_find_objects(options) ⇒ Object

Separate method for browsing objects, as it also needs to return whether or not there is another page of objects. Returns [another_page, objects], where another_page is true or false.



205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/scaffolding_extensions/meta_model.rb', line 205

def scaffold_browse_find_objects(options)
  get_options = {:order=>scaffold_select_order(:browse), :include=>scaffold_include(:browse), :conditions=>scaffold_session_conditions(options[:session])}
  if limit = scaffold_browse_records_per_page
    get_options[:offset] = (options[:page].to_i-1) * limit
    get_options[:limit] = limit = limit + 1
  end
  objects = scaffold_get_objects(get_options)
  if limit && objects.length == limit
    objects.pop
    [true, objects]
  else
    [false, objects]
  end 
end

#scaffold_column_name(column_name) ⇒ Object

Returns the human name for a given attribute. Can be set via the instance variable @scaffold_column_names, a hash with the column name as a symbol key and the human name string as the value.



223
224
225
226
227
228
229
230
231
232
# File 'lib/scaffolding_extensions/meta_model.rb', line 223

def scaffold_column_name(column_name)
  @scaffold_column_names ||= {}
  @scaffold_column_names[column_name] ||= if n = SCAFFOLD_OPTIONS[:column_names][column_name]
    n
  elsif scaffold_association(column_name)
    scaffold_associated_human_name(column_name)
  else
    column_name.to_s.humanize
  end 
end

#scaffold_column_options(column_name) ⇒ Object

Returns any special options for a given attribute. Can be set via the instance variable @scaffold_column_options_hash, a hash with the column name as a symbol key and the html options hash as the value.



237
238
239
240
241
# File 'lib/scaffolding_extensions/meta_model.rb', line 237

def scaffold_column_options(column_name)
  @scaffold_column_options_hash ||= {}
  @scaffold_column_options ||= {}
  @scaffold_column_options[column_name] ||= scaffold_merge_hashes(@scaffold_column_options_hash[column_name], SCAFFOLD_OPTIONS[:column_options][column_name], scaffold_column_type_options(scaffold_column_type(column_name)))
end

#scaffold_column_type(column_name) ⇒ Object

Returns the column type for the given scaffolded column name. Can be set via the instance variable @scaffold_column_types, a hash with the column name as a symbol key and the html type symbol as a value. Associations have the :association type, and other types are looked up via columns_hash.type. If no type is provided, :string is used by default.



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

def scaffold_column_type(column_name)
  @scaffold_column_types ||= {}
  @scaffold_column_types[column_name] ||= if type = SCAFFOLD_OPTIONS[:column_types][column_name]
    type
  elsif scaffold_association(column_name)
    :association
  elsif type = scaffold_table_column_type(column_name)
    (scaffold_convert_text_to_string && (type == :text)) ? :string : type
  else
    :string
  end
end

#scaffold_column_type_options(type) ⇒ Object

The HTML options for a given column type, affecting all columns of that type. Can be set with the @scaffold_column_type_options instance variable, which should be a hash with the column type as a symbol key and the html options hash as the value.



264
265
266
267
# File 'lib/scaffolding_extensions/meta_model.rb', line 264

def scaffold_column_type_options(type)
  @scaffold_column_type_options ||= {}
  @scaffold_column_type_options[type] ||= SCAFFOLD_OPTIONS[:column_type_options][type] || {}
end

#scaffold_field_id(field) ⇒ Object

Returns the foreign key for the field if it is an association, or the field as a string if it is not.



271
272
273
274
275
276
277
# File 'lib/scaffolding_extensions/meta_model.rb', line 271

def scaffold_field_id(field)
  if reflection = scaffold_association(field)
    scaffold_foreign_key(reflection)
  else
    field.to_s
  end
end

#scaffold_find_object(action, id, options) ⇒ Object

Find the object of this model given by the id



280
281
282
283
284
# File 'lib/scaffolding_extensions/meta_model.rb', line 280

def scaffold_find_object(action, id, options)
  object = scaffold_get_object(id)
  raise scaffold_error_raised unless scaffold_session_value_matches?(object, options[:session])
  object
end

#scaffold_find_objects(action, options) ⇒ Object

Find all objects of this model



287
288
289
# File 'lib/scaffolding_extensions/meta_model.rb', line 287

def scaffold_find_objects(action, options)
  scaffold_get_objects(:order=>scaffold_select_order(action), :include=>scaffold_include(action), :conditions=>scaffold_session_conditions(options[:session]))
end

#scaffold_habtm_associationsObject

Array of symbols for all habtm associations in this model’s scaffold_associations. Can be set with an instance variable.



293
294
295
# File 'lib/scaffolding_extensions/meta_model.rb', line 293

def scaffold_habtm_associations
  @scaffold_habtm_associations ||= scaffold_associations.reject{|association| scaffold_association_type(association) != :edit}
end

#scaffold_human_nameObject

The human name string for this model. Can be set with an instance variable.



298
299
300
# File 'lib/scaffolding_extensions/meta_model.rb', line 298

def scaffold_human_name
  @scaffold_human_name ||= scaffold_name.humanize
end

#scaffold_include(action = :default) ⇒ Object

Which associations to include when querying for multiple objects. Can be set with an instance variable.



304
305
306
# File 'lib/scaffolding_extensions/meta_model.rb', line 304

def scaffold_include(action = :default)
  @scaffold_include
end

#scaffold_merge_records(from, to, options) ⇒ Object

Merges the record with id from into the record with id to. Updates all associated records for the record with id from to be assocatiated with the record with id to instead, and then deletes the record with id from.

Returns false if the ids given are the same or the scaffold_session_value criteria is not met.



320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/scaffolding_extensions/meta_model.rb', line 320

def scaffold_merge_records(from, to, options)
  from, to = from.to_i, to.to_i
  return false if from == to
  from_object = scaffold_get_object(from)
  return false unless scaffold_session_value_matches?(from_object, options[:session])
  to_object = scaffold_get_object(to)
  return false unless scaffold_session_value_matches?(to_object, options[:session])
  scaffold_transaction do
    scaffold_all_associations.each{|reflection| scaffold_reflection_merge(reflection, from, to)}
    scaffold_destroy(from_object)
  end
  true
end

#scaffold_nameObject

The name string to use in urls, defaults to name.underscore. Can be set with an instance variable.



310
311
312
# File 'lib/scaffolding_extensions/meta_model.rb', line 310

def scaffold_name
  @scaffold_name ||= name.underscore.gsub('/', '__')
end

#scaffold_new_object(attributes, options) ⇒ Object

Creates a new object, setting the attributes if given.



335
336
337
338
339
340
# File 'lib/scaffolding_extensions/meta_model.rb', line 335

def scaffold_new_object(attributes, options)
  object = new
  scaffold_set_attributes(object, scaffold_filter_attributes(:new, attributes || {}))
  object.send("#{scaffold_session_value}=", options[:session][scaffold_session_value]) if scaffold_session_value
  object
end

#scaffold_remove_associated_objects(association, object, options, *associated_object_ids) ⇒ Object

Removes associated objects with the given ids from the given object’s association. Returns the associated object (if only one id was given), or an array of objects (if multiple ids were given).



345
346
347
348
349
350
351
352
353
354
355
356
# File 'lib/scaffolding_extensions/meta_model.rb', line 345

def scaffold_remove_associated_objects(association, object, options, *associated_object_ids)
  unless associated_object_ids.empty?
    scaffold_transaction do
      associated_objects = associated_object_ids.collect do |associated_object_id|
        associated_object = scaffold_association_find_object(association, associated_object_id.to_i, :session=>options[:session])
        scaffold_remove_associated_object(association, object, associated_object)
        associated_object
      end
      associated_object_ids.length == 1 ? associated_objects.first : associated_objects
    end
  end
end

#scaffold_search(options) ⇒ Object

Searches for objects that meet the criteria specified by options:

  • :null: fields that must be must be NULL

  • :notnull: matching fields must be NOT NULL

  • :model: hash with field name strings as keys and strings as values. uses the value for each field to search. Strings are searched based on substring, other values have to be an exact match.

  • :page: To determine which offset to use

Returns [form_params, objects], where form_params are a list of parameters for the results form (for going to the next/previous page), and objects are all of the objects that matched.



369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# File 'lib/scaffolding_extensions/meta_model.rb', line 369

def scaffold_search(options)
  conditions = []
  search_model = options[:model] || {}
  object = scaffold_search_object(search_model)
  null = options[:null]
  notnull = options[:notnull]
  form_params= {:model=>{}, :null=>[], :notnull=>[], :page=>options[:page]}
  
  limit, offset = nil, nil
  if scaffold_search_pagination_enabled?
    limit = scaffold_search_results_limit + 1
    offset = options[:page] > 1 ? (limit-1)*(options[:page] - 1) : nil
  end
  
  if search_model
    scaffold_attributes(:search).each do |field|
      fsym = field
      field = field.to_s
      next if (null && null.include?(field)) || \
          (notnull && notnull.include?(field)) || \
          search_model[field].nil? || search_model[field].empty?
      case scaffold_column_type(fsym)
        when :string, :text
          conditions << scaffold_substring_condition(field, object.send(field))
        else
          conditions << scaffold_equal_condition(field, object.send(field))
        end
      form_params[:model][field] = search_model[field] if scaffold_search_pagination_enabled?
    end
  end
  
  scaffold_attributes(:search).each do |field|
    field = field.to_s
    if null && null.include?(field)
      conditions << scaffold_null_condition(field)
      form_params[:null] << field if scaffold_search_pagination_enabled?
    end
    if notnull && notnull.include?(field)
      conditions << scaffold_notnull_condition(field)
      form_params[:notnull] << field if scaffold_search_pagination_enabled?
    end
  end
  
  conditions << scaffold_session_conditions(options[:session])

  objects = scaffold_get_objects(:conditions=>conditions, :include=>scaffold_include(:search), :order=>scaffold_select_order(:search), :limit=>limit, :offset=>offset)
  if scaffold_search_pagination_enabled? && objects.length == scaffold_search_results_limit+1
    form_params[:next_page] = true
    objects.pop
  end
  [form_params, objects]
end

#scaffold_search_null_optionsObject

List of human visible names and field name symbols to use for NULL/NOT NULL fields on the scaffolded search page. Can be set with an instance variable.



424
425
426
# File 'lib/scaffolding_extensions/meta_model.rb', line 424

def scaffold_search_null_options
  @scaffold_search_null_options ||= scaffold_attributes(:search).reject{|f| scaffold_table_column_type(f).nil?}.collect{|f| [scaffold_column_name(f), f]}
end

#scaffold_search_object(attributes = {}) ⇒ Object

Returns a completely blank object suitable for searching, updated with the given attributes.



429
430
431
432
433
434
435
436
437
438
439
440
441
# File 'lib/scaffolding_extensions/meta_model.rb', line 429

def scaffold_search_object(attributes = {})
  object = new

  # Blank any fields set by default
  scaffold_attributes(:search).each{|field| object.send("#{field}=", nil) unless object.send(field) == nil}

  # Don't set any fields left blank by the user
  h = {}
  attributes.each {|k,v| h[k] = v unless v.to_s.strip.empty?}

  scaffold_set_attributes(object, h)
  object
end

#scaffold_select_order(action = :default) ⇒ Object

The SQL ORDER BY fragment string. Can be set with an instance variable.



444
445
446
# File 'lib/scaffolding_extensions/meta_model.rb', line 444

def scaffold_select_order(action = :default)
  @scaffold_select_order
end

#scaffold_session_conditions(session) ⇒ Object

The conditions array to use if scaffold_session_value is set, nil otherwise



449
450
451
# File 'lib/scaffolding_extensions/meta_model.rb', line 449

def scaffold_session_conditions(session)
  ["#{scaffold_table_name}.#{scaffold_session_value} = ?", session[scaffold_session_value]] if scaffold_session_value
end

#scaffold_session_value_matches?(object, session) ⇒ Boolean

True if the given object meets the scaffold_session_value criteria

Returns:

  • (Boolean)


454
455
456
# File 'lib/scaffolding_extensions/meta_model.rb', line 454

def scaffold_session_value_matches?(object, session)
  !scaffold_session_value || object.send(scaffold_session_value) == session[scaffold_session_value]
end

#scaffold_show_association_links?(association) ⇒ Boolean

Whether to show associations links for the given association. Generally true unless it is an :has_and_belongs_to_many association and scaffold_habtm_with_ajax is true.

Returns:

  • (Boolean)


460
461
462
# File 'lib/scaffolding_extensions/meta_model.rb', line 460

def scaffold_show_association_links?(association)
  !(scaffold_habtm_with_ajax && scaffold_association_type(association) == :edit)
end

#scaffold_table_class(type) ⇒ Object

Returns the scaffolded table class for a given scaffold type. Can be set with the instance variable @scaffold_table_classes, a hash with the type as the symbol key and the value as the html class string.



467
468
469
470
# File 'lib/scaffolding_extensions/meta_model.rb', line 467

def scaffold_table_class(type)
  @scaffold_table_classes ||= {}
  @scaffold_table_classes[type] ||= SCAFFOLD_OPTIONS[:table_classes][type]
end

#scaffold_transaction(&block) ⇒ Object

Run the block inside a database transaction



473
474
475
# File 'lib/scaffolding_extensions/meta_model.rb', line 473

def scaffold_transaction(&block)
  transaction(&block)
end

#scaffold_unassociated_objects(association, object, options) ⇒ Object

Returns all objects of the associated class not currently associated with this object.



478
479
480
# File 'lib/scaffolding_extensions/meta_model.rb', line 478

def scaffold_unassociated_objects(association, object, options)
  scaffold_associated_class(association).scaffold_get_objects(:conditions=>[scaffold_unassociated_condition(association, object), scaffold_associated_class(association).scaffold_session_conditions(options[:session])], :order=>scaffold_select_order_association(association), :include=>scaffold_include_association(association))
end

#scaffold_update_attributes(object, attributes) ⇒ Object

Updates attributes for the given action, but does not save the record.



483
484
485
# File 'lib/scaffolding_extensions/meta_model.rb', line 483

def scaffold_update_attributes(object, attributes)
  scaffold_set_attributes(object, scaffold_filter_attributes(:edit, attributes))
end

#scaffold_use_auto_completeObject

Whether this class should use an autocompleting text box instead of a select box for choosing items. Can be set with an instance variable.



489
490
491
# File 'lib/scaffolding_extensions/meta_model.rb', line 489

def scaffold_use_auto_complete
  @scaffold_use_auto_complete ||= scaffold_auto_complete_options[:enable]
end