AjaxScaffold has been deprecated in favour of ActiveScaffold
The aim of this post is to show how to extend or replace the default functionality of the Ajax Scaffold plugin (ASp). I will go over two areas, firstly how you filter the dataset the table displays, and secondly the methods you can override to really gain control.
Simple Filtering of the Dataset
In order to filter the data that the table displays you need to simply override a single method (for each model) in your controller.
conditions_for_{table_name}_collection
This method is expected to return the same array that the Rails find() method accepts as its :conditions parameter.
Lets take a simple user model as an example. The db table has the following columns: id, name, password, employer_id where the employer_id represents a has-one relationship to the user’s employer (represented by another table). Now lets say we only want to see users from the current employer in our table, then all we need to do is define the following method in our controller:
def conditions_for_users_collection [ 'employer_id = ?', params[:current_employer] ] end
This of course assumes that the current request defines :current_employer as the employer’s id.
You can use any conditional statements you like, if they would work in the Rails find() method, they will work here.
More Complex Filtering
At a lower level the collection used by the table is provided by a combination of three methods:
- count_{table_name}_collection(model, options)
- page_and_sort_{table_name}_collection(model, options, paginator)
- page_and_sort_{table_name}_collection_with_method(model, options, paginator)
These methods represent a slightly extended version of the methods found in the Rails paginator. The first two are called for any normal page or sort (i.e not using a ScaffoldColumn defined using the :sort parameter) and the last is called only for ScaffoldColumns defined with, wait for it, the :sort parameter.
For example lets say we have a set of Report objects that are displayed using the following column definitions:
@@scaffold_columns = [
AjaxScaffold::ScaffoldColumn.new(Report, {
:name => "title",
:eval => "row.current_definition.title",
:sort => 'current_definition.title'}),
AjaxScaffold::ScaffoldColumn.new(Report, {
:name => "viewed",
:eval => "row.views",
:sort => 'views' }),
]
We also have defined a method that returns the reports for a particular project, or the reports for a project in a particular category (all of which would be difficult to do with a simple :conditions statement):
def get_reports
project = get_project
reports = project.reports
if request.post?
selected_category = params[:category]
reports = project.reports_for_category(selected_category) if selected_category
end
reports
end
We could then define the three methods above as follows (in ReportsController.rb):
def count_reports_collection(model, options)
get_reports.size
end
def page_and_sort_reports_collection_with_method(model, options, paginator)
collection = get_reports
order_parts = options[:order].split(' ')
sort_collection_by_method(collection, order_parts[0], order_parts[1]).slice(paginator.current.offset,options[:per_page])
end
def page_and_sort_reports_collection(model, options, paginator)
page_and_sort_reports_collection_with_method(model, options, paginator)
end
This would cause every sort / page to use the with_method methods, as we need due to all columns using the :sort parameter. Our count would come from our get_reports method and everything should work as expected.
Other Extension Points
Here are some of the other methods that you can override to change the behaviour of the scaffold, its probably a good idea to actually look at the plugin code to see how each method is used, although some are pretty self explanatory.
In all of these {prefix} is defined as {table_name}_.That is the table name with an underscore appended. {suffix} is defined as _{model_name_in_lower_case}. That is the model name in lower case with an underscore prepended. These are only required in multi table scenarios (I have written it like this here to match the actual code). The reason for doing this is to give CRUD like methods when only using a single table.
Default Sort Column
By default the rows are sorted using the primary key, id. To change this you can override: default_sort / default_{prefix}sort
def default_{prefix}sort
"users.name"
end
Default Sort Direction
To change this from ‘asc’ you can override: default_sort_direction / default_{prefix}sort_direction. The only other possible return value is “desc”.
def default_{prefix}sort_direction
"desc"
end
Create
If you want to change the default behaviour when a model is created you can override the following method which is called internally:
def do_create#{suffix}
@user = User.new(params[:user])
@successful = @user.save
end
Update
If you want to change the default behaviour when a model is updated you can override the following method which is called internally:
def do_update#{suffix}
@user = User.find(params[:id])
@successful = @user.update_attributes(params[:user])
end
Table
To add custom behvaiour to the table rendering you can use this method. This is really to add functionality, you still need to call the methods as shown or things may go a little wrong:
def #{prefix}table
self.#{prefix}table_setup
OTHER CODE GOES IN HERE
render#{suffix}_template(:action => 'table')
end
Added in 3.2.2
New
Called before the new form appears
def do_new#{suffix}
@user = User.new
@successful = true
end
Edit
Called to find the object to edit
def do_edit#{suffix}
@user = User.find(params[:id])
@successful = !@user.nil?
end
Destroy
Called to find and destroy an object
def do_destroy#{suffix}
@successful = User.find(params[:id]).destroy
end
No Responses to “Extending the Ajax Scaffold Plugin”
Sorry, the comment form is closed at this time.












Thank you for your helpful tutorial. I’m new to RoR and have found your scaffold plugin very helpful.
Is there a way to only filter the dataset for a table under certain conditions? I would like to display the table with all data on one page and a subset of the data on another page. I’m using render_component :action => ‘table’. With the filter example, I can get the correct subset but I don’t know how to have the full set sometimes and the subset sometimes.
Thanks.
Hi Jo, you can just pass parameters in the component call to use in the decision making process:
render_component :action => ‘table’, :params => params.merge(:filter => ‘all’)
or something.
Cheers
Scott
H,I override the method do_update#{suffix},but there is a exception when I do "edit" option,why?
thanks.
Hi, I suspect because you are now using "ActiveScaffold":http://www.activescaffold.com. You will need to refer to those docs for customization. The original AjaxScaffold plugin is now deprecated.
Cheers
Scott
Does anyone knows how to get FCKEDITOR to be saved to the database while editing in the activescaffold ?
I’ve used a column overide to load the Fckeditor but it doesn’t allow me to save it to the database.