advanced.txt

doc/advanced.txt
Last Update: 2008-10-18 19:13:56 -0700

Here are some advanced features of the plugin:

scaffold_session_value

You can define this attribute in your model to control access to the model's objects based on a session variable. For example, if you want to limit a users access via the scaffold to only objects that match his id, you can set the following in the model:

class Car < ActiveRecord::Base
  @scaffold_session_value = :user_id
end

Make sure that the session value is set to :user_id when the user logs in:

session[:user_id] = User.id

Then, the user will only be able to see cars where car.user_id is equal to session. Any cars the user creates via the scaffolded forms will have user_id set correctly.

You should make sure that :user_id is not in the @scaffold_fields for the model (which it will be by default).

Eager loading

You can eagerly load associations when loading multiple model objects, via @scaffold_include. Here's an example scaffold_name (for an accounting entry):

def scaffold_name
  "#{date.strftime('%Y-%m-%d')}-#{reference}-#{entity.name if entity}-#{debit_account.name if debit_account}-#{credit_account.name if credit_account}-#{money_amount}"
end

Without @scaffold_include, this will cause 3 queries for each model object that calls scaffold_name. However, if you add @scaffold_include to eagerly load the associations, there won't be any additionally queries:

@scaffold_include = [:entity, :credit_account, :debit_account]

Autocompleting

Autocompleting is easy to set up in the model via:

@scaffold_use_auto_complete = true

Any time the scaffold would use a select box to show a group of objects, it will instead use an autocompleting text box, allowing you to easily support a much greater number of objects (select boxes aren't good for collections with thousands of objects). If the model doesn't have an SQL column named “name”, you'll need to specify how to construct the SQL query for the object via:

@scaffold_auto_complete_options = {:sql_name=>'LOWER(name)', 
  :format_string=>:substring,  :search_operator=>'LIKE', 
  :results_limit=>10, :phrase_modifier=>:downcase}

The defaults are shown. You'll most likely need to change the :sql_name. If you are using PostgreSQL, you'll probably want to include:

{:sql_name=>'name', :search_operator=>'ILIKE', :phrase_modifier=>:to_s}

PostgreSQL can do case insensitive searching via ILIKE, and there is no reason to force the attribute or the search phrase to lowercase.

You can get quite advanced, incorporating other tables if you use @scaffold_include. Here's an example from an accounting application:

@scaffold_select_order = 'entries.date DESC, entities.name, accounts.name, debit_accounts_entries.name, entries.amount'
@scaffold_include = [:entity, :credit_account, :debit_account]
@scaffold_auto_complete_options = {:sql_name=>"reference || date::TEXT || entities.name ||  accounts.name || debit_accounts_entries.name || entries.amount::TEXT", :search_operator=>'ILIKE', :phrase_modifier=>:to_s}

Note how :sql_name can pull in data from multiple tables, since they are specified via @scaffold_include. Note that the syntax might be database specific (the accounting applation only supports PostreSQL).

Customization

Scaffolding Extensions is extremely customizable. The database layer is split from the presentation layer, and most of the interface between them has support for overriding based on either the association or action given.

For example, if you want different fields shown on the show page than on the edit page (to make certain fields read only), you can define:

@scaffold_show_fields = [:name, :amount]
@scaffold_edit_fields = [:name]

Each of the different pages (e.g. new, browse, search, etc.) can have a different @scaffold_fields, @scaffold_select_order, or @scaffold_include via the above method. You can also override any of those variables for a given association displayed on the edit page. For example, let's say you have an Employee model which belongs_to a Position model. When you bring up the edit page for the employee, you will have a select box with all of the positions shown by default (with the currently associated position selected by default). This select box by default uses the @scaffold_select_order and @scaffold_include of the Position model, but you can override it just for its appearance on the employee's edit page via:

class Employee < ActiveRecord::Base
  @scaffold_position_select_order_association = ...
  @scaffold_position_include_association = ...
end

You can even change how the find is performed by defining a class method:

class Employee < ActiveRecord::Base
  def self.scaffold_position_association_find_objects(options)
    # This will be called to get the collection of positions
    # for the select box.  The object on the edit page is in
    # options[:object], in case you want to use that
    # to filter the selection of possible objects
  end
end

This barely scratches the surface of customization possibilities, see the RDoc for details on which methods can be customized in this manner.

has_and_belongs_to_many scaffolding

Scaffolding Extensions scaffolds all has_and_belongs_to_many associations via links on the edit page. You can limit which associations are scaffolded via the model's @scaffold_habtm_associations. By default, habtm scaffolding is enabled via a separate page with two select boxes, one choosing objects not currently associated that can be added, and the other showing currently associated objects that removed from the association.

It is possible to change this to scaffold habtm associations on the edit page via a couple of Ajax enabled controls. This is set with the model's @scaffold_habtm_with_ajax variable. With that variable set, directly under the main edit form for the model will be select boxes with possible objects to associate (or autocompleting text boxes if the association's model uses autocompleting), as well as a button that adds those objects to the association via Ajax. There is also a list of currently associated objects that can be removed from the associated via Ajax. This allows for quick modification of habtm associations.

merge scaffolding

By default, Scaffolding Extensions will produce a merge scaffold for every model. Merging object A into object B will take all of the has_many and has_and_belongs_to_many association objects for object A and will instead associated them with object B. It will then delete object B. This can be used to fix issues caused by database denormalization.

search scaffolding

By default, Scaffolding Extensions will produce a simple search scaffold for every model. It will allow searching by substring for columns of type :text or :string, and exact matches for other columns.