You are here: Browse Railsplugins Scaffolding Extensions
The Scaffolding Extensions plugin enhances Rails’ default scaffolding in the following ways:
Please note that this does not affect the scaffold generator (script/generate scaffold). This plugin only affects the scaffold method. It is designed to replace the generator by being customizable enough so that you would not need to modify its output. However, there is support for outputing the controller code generated by the scaffold method (see below).
This plugin should be compatible with Rails 1.2. Older versions are compatible with Rails 1.1.x (svn revision 61), but the current version is not. It is not tested on Edge Rails, it always targets the latest stable Rails version.
svn: svn://suven.no-ip.org/rails/plugins/scaffolding_extensions file: http://suven.no-ip.org/scaffolding_extensions.tar.gz
In an existing Rails application, create a controller (i.e. “script/generate controller crud”), and modify so it looks like:
class CrudController < ApplicationController
scaffold_all_models
end
Then go to the index page for the controller (e.g. http://website/crud). You’ll see a link to a management page for each of your models. Each management page has links to create, delete, edit, show, search, and merge pages for the model. The pages should be usable right away, but you’ll want to add some configuration code to your models to specify the default names to display in select boxes, attributes to show on the forms, associations to show, whether to use select boxes or autocompleting text boxes, etc..
Recent versions of the plugin are more strict than previous versions in the arguments to scaffold and scaffold_habtm. Originally I thought that using singularize on an already singular word (or pluralize on an already plural word) would have no effect (like using camelize on an already camelized word). However, this isn’t the case and can cause bugs for some common words (notably things ending in “ss”), so now you must you the singular, underscored, form:
scaffold :artist # Works
scaffold :albums # Doesn't work
scaffold :album, :habtm=>:artist # Yes
scaffold :artist, :habtm=>albums # No
scaffold_habtm :album, :artist # Dice
scaffold_habtm :albums, :artists # No Dice
scaffold_habtm :album, :artists # Still No Dice
I chose to use the singular form even for the habtm forms as that is the one the documentation has always used. Note that if you just use scaffold_all_models, you don’t need to worry about this.
An addition to the new scaffold features that this plugin adds (merge, search, belongs_to, and habtm scaffolding), the major attraction of this plugin is the ability to customize the scaffolding by adding some code to the model class. Let’s start with the most common customizations:
class Album < ActiveRecord::Base
has_and_belongs_to_many :artists
belongs_to :genre
@scaffold_fields = %w'name rating genre numtracks'
@scaffold_select_order = 'name'
@scaffold_column_names = {:numtracks=>'Number of Tracks'}
@scaffold_auto_complete_options = {}
def scaffold_name
name[0...50]
end
end
@scaffold_fields determines which fields are shown in the new, edit, and search forms (which use the order specified). It defaults to content_columns plus belongs_to associations. @scaffold_select_order determines which order is used in the SQL ORDER clause when displaying a list of albums (for example, from the edit link of the management page). @scaffold_column_names specifies the visible names for each attribute. @scaffold_auto_complete_options turns on autocompleting for the model, instead of using select boxes (necessary for a decent response time if you have a large number of records). scaffold_name determines the name to use for each album inside those select boxes. Note that it is a method and not a variable, so you need to specify a ruby instance method for it.
Notice in this case that genre was specified. In this case, our schema has genre_id as a foreign key to the genres table. If you specified genre_id, you’d get a usual text input box for the foreign key integer. If you specify genre (the name of the belongs_to association), instead of a text input box, you will get a select box with all genres, allowing you to pick one. It will use the @scaffold_select_order variable and scaffold_name method in the Genre model to format the select box. If you have @scaffold_auto_complete_options set in the Genre model, there will be an autocompleting text box instead of a select box (though since there aren’t that many genres, you would probably be better off with a select box in this case).
There are also a couple of customizations that can be set in the controller:
There are some other lessor used options which allow you to:
Consult the RDoc if you would like more information on these (and other options).
In many cases, if you are just using the plugin to create an easy administrative front end to your existing application, it will probably be easier to use scaffold_all_models instead of following the instructions below, as that takes care of things for you. The instructions below predate the introduction of scaffold_all_models, and show how different options passed to the scaffold method affect the creation of the scaffolding. They will mainly be useful if you are using the scaffolding for non administrative forms.
Generally, the scaffolding extensions are used in same way as the normal scaffolding. Inside a controller, add:
scaffold :album
In addition to the normal options, this plugin adds the following options to the scaffold method:
So these is are valid calls to scaffold:
scaffold :album, :suffix=>true, :except=>:delete, :habtm=>[:artist]
scaffold :artist, :only=>[:new, :edit, :search, :manage], :habtm=>:album
Let’s say you just do the simplest possible command (scaffold :album). Then you go to the index of the controller. You’ll notice some differences. The default Rails scaffold page has a paginated table of records. This plugin changes that to a simple management page with the following links:
Clicking on show, destroy, or edit links will bring up a simple select box allowing you to choose a record to show, destroy, or edit. Clicking on new will bring you to a form that allows you to create a new object (similar to the default form, with slightly different formatting). Clicking on search will bring up a simple search form for searching on any of the fields in the new or edit form (the search results page looks similar to the default Rails list page). Clicking on merge will bring up a page with two select boxes, allowing you to merge two records of the same type (by updating the necessary associations and then deleting the record to be merged). Clicking on browse brings up a paginated table of records similar to the search results.
If you specified any actions in :except (or didn’t include them in :only), the appropriate links won’t appear in the management page. If you specified :manage in :except, the management page won’t be created. The scaffold methods that are available for use in :except and :only are:
[:manage, :show, :destroy, :edit, :new, :search, :merge, :browse]
Let’s say you used the command:
scaffold :artist, :only=>[:new, :edit, :search, :manage], :habtm=>:album
The manage page would look like:
If you click on the edit albums link and select an album, you’ll notice that below the entry form for updating the album are all of the items associated with the current item (unless you overrode it using the @scaffolded_associations variable in the model). Assuming you use :suffix=>true when creating scaffolds and create scaffolds for multiple models in the same controller, the associated items will be linked so that they can be easily edited.
If you just want to create habtm scaffolds, there is a command that does so:
scaffold_habtm(:artist, :album)
By default, this will create the habtm scaffold both ways. You can go to edit_album_artists/42 to edit the artists for album 42 and edit_artist_albums/42 to edit the albums for artist 42.
The plugin now includes functions that make it easier to test. The testing isn’t comprehensive, as it doesn’t test if the forms work, it just tests to see if you can successfully request the displayed pages. Still, it is useful to see if any errors are produced due to naming conflicts (which can be resolved by adding some configuration code to the model or changing the arguments to the scaffold method call). For example:
class CrudControllerTest < Test::Unit::TestCase
def setup
@controller = CrudController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
test_scaffold_all_models
# or test_scaffold :album
end
Consult the RDoc if you want view more testing options.
I don’t recommend using the generated code for anything more than debugging, but if you want to see the code that is generated, try this for a single model:
script/runner "puts ActionController::Base.scaffold(:model, \
:generate=>true)"
or this for all models:
script/runner "puts ActionController::Base.scaffold_all_models( \
:generate=>true)}"
Feel free to contact me at jeremyevans0@gmail.com if you have any questions about this plugin.
NOTE: This description has been extracted from the Plugin README and so the formatting may need updating to make browser friendly