AjaxScaffold has been deprecated in favour of ActiveScaffold

Install

The easiest way to install the plugin version of Ajax Scaffold (AS) is to use the inbuilt Rails installer script. Simply run the following command from the root of your Rails app:

ruby script/plugin install svn://rubyforge.org/var/svn/ajaxscaffoldp/trunk

This will fetch the plugin into ‘vendor/plugins’. The files required by the plugin (views, css and js) will then be copied over to the app on startup.

Basic Usage

With the plugin installed simply adding the following line:

ajax_scaffold :model_name_in_lower_case

to the top of any ActionController class, will result in the creation of the swath of CRUD methods required for Richard White’s great AJAX front end.

Then stick this in your layout:

<%= ajax_scaffold_includes %>

Voila!!! The full AS table will then be available at: http://my_server_address/my_controller_name/

For example – lets say we wanted to create a simple user administration interface. First off we generate the users model:

ruby script/generate model user

Then create the users table in the database using the following migration.

create_table "users" do |t|
  t.column "name", :string, :limit => 255, :null => false
  t.column "password", :string, :limit => 255, :null => false
  t.column "created_at", :datetime, :null => false
  t.column "updated_at", :datetime, :null => false
end

Now, generate a controller:

ruby script/generate controller users

Open the controller file, users_controller.rb and add the plugin include:

class UsersController < ApplicationController
  ajax_scaffold :user
end

Create a layout file called users.rhtml:

<!DOCTYPE html
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
  <title>Users</title>
  <%= ajax_scaffold_includes %>
</head>
<body>

   <%= @content_for_layout %>

</body>
</html>

Start Webrick, point your favourite browser (Firefox, of course) at http://localhost:3000/users and ……… you should see this:



Now you can go ahead and add, edit, page, and sort your users. Of course in real life having plain text passwords would probably be frowned upon and there is no validation but you get the idea.

Options

So you’ve got a table, what else does it do? Ok, there are a few options that can be passed to the plugin that affect the behaviour and appearance. These are:

except- this takes an array of any of these strings: “create”, “edit”, “delete” and prevents the generation of the corresponding method. This also removes the appropriate elements from the displayed table.

e.g ajax_scaffold :user, :except => [‘create’, ‘delete’]

would create a controller with no create or delete methods.

width – this takes a number representing the width in pixels of the generated table.

e.g ajax_scaffold :user, :width => 500

creates a table of width 500px.

rel_width – this takes a number between 0 and 1 representing the relative width of the table to its containing element.
e.g ajax_scaffold :user, rel_width => 0.7
produces a table of 70% width

rows_per_page – this dictates the maximum number of rows displayed before pagination

e.g ajax_scaffold :user, :rows_per_page => 10

totals – this takes an array of strings representing the names of the columns that you would like totals to be created for. If not null this option causes a totals row to be added to the bottom of the table.

e.g ajax_scaffold :user, :totals => [‘login_cnt’]

would produce a row showing the total number of logins for all the users on the page (assuming of course our model had an incrementing field called login_cnt, see later for another example).

suffix – this emulates the suffix option of the Rails scaffold and when set to true generates all the methods specific to the model allowing for multiple tables to be placed within a single controller (see following section)

Mutiple Scaffolds on a Page

There are two ways to place mutiple tables on a single page, the first (and probably the approved REST / CRUD way) is to create a controller for each model that you wish to have a table for. Setup each table as required using the options to the ajax_scaffold method and then simply include each table in a single rhtml file using a call to render the component.

<%= render_component :controller => '/users', :action => 'table', :params => params %>
<%= render_component :controller => '/articles', :action => 'table', :params => params %>
<%= render_component :controller => '/pages', :action => 'table', :params => params %>

If however, you don’t want to go down that path, say you just want an admin controller to administrate the user, article and page models the you can do all this with a single file. Simply create an ‘admin’ controller and declare each model with a separate ajax_scaffold call. Make sure to pass the ’:suffix => true’ option:

class AdminController < ApplicationController
  ajax_scaffold :user, :rows_per_page => 3, :suffix => true, :width => 500
  ajax_scaffold :article, :except => ['edit'], :suffix => true, :rel_width => 0.4
  ajax_scaffold :page, :except => ['delete'], :rows_per_page => 10, :suffix => true, :width => 400

  def index
  end
end

The index page (don’t forget to add the index method) will then look slightly different, with the calls to table now using the prefix of the model name:

<%= render_component :controller => '/admin', :action => 'users_table', :params => params %>
<%= render_component :controller => '/admin', :action => 'articles_table', :params => params %>
<%= render_component :controller => '/admin', :action => 'pages_table', :params => params %>

This setup (with a bit of data added) gives:

Totalled Columns

Now suppose you want to add totals for the “views” columns in the articles and pages tables. Easy. Just change the declaration in the controller to:

class AdminController < ApplicationController
  ajax_scaffold :article, :except => ['create','edit'], :suffix => true, :rel_width => 0.4, :totals => ['views']
  ajax_scaffold :page, :except => ['delete'], :rows_per_page => 5, :suffix => true, :width => 500, :totals => ['views']

  def index
  end
end

Now we get (note the create method has been dropped of the articles table):

Customizing the View

On startup the plugin creates a directory called ajax_scaffold in app/views. This contains all the views required by AS. If you want to alter one of the templates simply copy it to the appropriate views directory and update it.

The search path employed by the plugin is as follows:

  1. app/views/model_name
  2. app/views/controller_name
  3. app/views/ajax_scaffold

So for our example with an admin controller, and then user, article and page models we could override the table.rhtml for all tables displayed by placing our custom template in “app/views/admin”. We could then have a user specific form by placing _form.rhtml in “app/views/user”. The article and page models would keep using the generated form from app/views/ajax_scaffold.

No Responses to “Getting Started with the Ajax Scaffold Plugin”

  1. @Anthony – Cheers. The habtm stuff keeps cropping up and I just haven’t had time yet to go through it. Its on the radar though.

    @Terry – Update, just to confuse things I have also got installs that work fine on IE. Brilliant…..

    Scott.

  2. After some investigation, I have narrowed the IE6 top/bottom border issue to the presence of a single line in the generated html for the page. Here are the details of the experiment:
    I created two ajax_scaffold pages from the user model described in the howto above – one via the ajax_scaffold generator, and the other using the plugin as described in the howto. I verified that the generator-based page renders properly, and that the the plugin-based page has an extended border. I saved the resultant html for both pages via browser view-source as working.html and broken.html. I placed these files in the scaffoldp/public folder so that the following url would render the pages with working styles and images:
    http://localhost/demo6/vendor/plugins/ajaxscaffoldp/public/broken.html
    I modifed each html file so that all references to css, js and image files would be valid in the new location. I verified that the behavior of these pages was as expected: broken.html had an extended border and working.html did not. Doing a side by side comparison of these files, and moving/replacing successively smaller pieces of working.html into broken.html, I determined that removing the following line from broken.html fixed the border issue:

    OPENANGLEBRACKET script src="/demo6/vendor/plugins/ajaxscaffoldp/public/javascripts/dhtml_history.js?1159500944" type="text/javascript"> OPENANGLEBRACKET /script CLOSEANGLEBRACKET

    (OPENANGLEBRACKET and CLOSEANGLEBRACKET added here to protect the script ref.)
    When I add this line back into broken.html, it is again broken. I have not drilled any deeper than this yet, but if this doesn’t ring any bells, I’ll keep investigating.

  3. Hi Terry,

    Thanks for all your investigation, I think that will be enough for me to fix the issue. I’ll be putting out a release tomorrow which I plan to have this fixed in.

    Thanks
    Scott.

  4. Hi Scott, great work.

    I was able to install and properly run the generator, but I am having difficulty getting the plugin.
    If I do:

    ruby script/plugin install svn://rubyforge.org/var/svn/ajaxscaffoldp/trunk

    the script exits after a pause, without errors, and nothing gets installed. I must be doing something wrong…
    Thanks for your patience!

    Giuseppe

  5. Hi Guiseppe,

    I have just tried that command and it works for me. Other people who have had similar problems have found that their firewall was blocking access to the svn at rubyforge.

    You could just download the zip or the tar from here:

    http://rubyforge.org/projects/ajaxscaffoldp/

    Cheers
    Scott.

  6. Hi Scott,

    thanks for the feedback. I am sure you have much better things to do, but–I had already downloaded the zip/tgz package from rubyforge, and have been unable to properly install it.

    I guess I cannot figure out how to install a plugin from a local source (name and location of source folder, command options, etc.). It seems like a very basic task, but I can’t seem to find the relevant info on the web.

    My attempts to do:
    ruby script/plugin install local_path_to_plugin_dir
    have failed.

    Apologies for abusing this post and your time, and thanks again.

    Giuseppe

  7. Hi again Scott, never mind my previous post. I have just discovered the miraculous fact of life (on rails) that installing a plugin quite simply means to place its directory structure into vendor/plugins (hoping I am not missing something).

    WOW :-)

    I feel ready to try and get AS and Golberg to act nice to one another…

    Ciao,
    Giuseppe

  8. Hi Giuseppe – nop thats all it takes ;)

    Glad you got it working. Scott.

  9. I grabbed the latest plugin code today, and it looks like you fixed the border issue – that’s great! I’m quite curious about what was causing the issue. I’ll do a diff with the previous version. Thank you Scott!

    -terry

  10. Is it just me, or do the contents of <pre>view/ajax_scaffold</pre> get rewritten every time you restart the server?

    If so, is this the default behavior for plugins, or is this specific to this plugin? Assuming my controller is "products" and I want to alter the code for <pre>view/ajax_scaffold/_column_headings.rhtml</pre>, I know I can get around this by creating an altered version at <pre>view/products/_column_headings.rhtml</pre>, but I want to make several controllers reflect the same changes.

    Surely there’s an easy way to do this (not necessarily by disabling the plugin’s apparent rewriting "feature")?

    PS: I love to imagine how this will likely turn out: I’ll be humbled and awed by the simplicity of the solution. Thanks rails! Sincerely, a former PHP guy.

  11. @Terry, we just used the IE star hack to force the width to behave.

    @Anthony, you are right at the moment that is the behaviour although we are looking to change that. The easiest way to achieve the result you are looking for is to change the template in the plugin directory then that will be copied across. Of course you will need to remember to copy the change over when you update the plugin.

    Cheers
    Scott

  12. First off, I’d like to also say thanks for all the work on this plugin. This is really good stuff. I’m trying to use the ajaxscaffold as a plugin. If I use the script/plugin install; then it works just fine. But, I would rather use:

    gem install ajax_scaffold_plugin

    This installs just fine, but no matter what I do (require ‘ajax_scaffold_plugin’ or anything else), I can’t seem to get:

    ajax_scaffold :model_name_in_lower_case

    Should the plugin work as a gem? (I haven’t copied anything over to my project).

    Thanks! — Marcus

  13. Hi Marcus – the plugin needs to be installed on an app by app basis so installing it as a gem won’t work. It has to go in vendor/plugins. The gem is just there as another archive.

    Cheers
    Scott

  14. How do I go about integrating ajaxscaffold with substruct? I tried going into the substruct plugin area, modifying a controller and layout file, but it crashed.

    BTW, great work on this plugin!

  15. Hi. Regarding the legacy primary key\table names, I have a fix that seems to work. I modified default_#{prefix}sort somewhere near line 374 be the following. <pre>
    def default_#{prefix}sort
    eval("#{class_name}.table_name") + "." + eval("#{class_name}.primary_key")
    end
    </pre>
    It takes the table_name and primary_key from the model class.
    I am still learning so there might be a much better way.<br>
    Cheers,
    Michael.

  16. @Henry, sorry for some reason I only just saw your comment. However, I’ve never used Substruct myself so I can’t really help you there. Others may though so you could try asking on the forum.

    @Michael, those evals shouldn’t be required. Apart from that though this is bascially the code that is in the upcoming version, so your issue will remain fixed in that. Thanks for the feedback.

    Cheers
    Scott.

  17. when I run:
    ruby script/plugin install svn://rubyforge.org/var/svn/ajaxscaffoldp/trunk

    from the command line, nothing happens. I decided to tack a "2" on the end just to test to see what happens and I get the same result from above, absolutely nothing. ?

  18. Hi Mark, that works for me. Are you behind a firewall? Scott.

  19. Ive just set up using the plugin, have:

    class OriginController < ApplicationController

    ajax_scaffold :o rigin

    end

    class Origin < ActiveRecord::Base

    ajax_scaffold :model_name_in_lower_case

    has_many :leads, :foreign_key => ‘howdidyouhear’

    end

    [ .. ]

    fire up mongrel on 3000, and when I hit

    http://localhost:3000/origin I get: `const_missing’: uninitialized constant Origin [.. ]

    Can anyone tell me what glaring mistake I must be making here? Thanks

  20. Hi R, you don’t need to put the scaffold call in your models only the controller.

    Cheers
    Scott.

  21. "Hi Mark, that works for me. Are you behind a firewall? Scott."

    Well, I don’t think so… but maybe. Wouldn’t the ruby install call show some kind of error if it cannot connect? I get back no response at all.

    Thanks,
    Mark

  22. What if I just download the entire plugin zip from rubyforge. Do I just unzip it in the base directory? I tried that, but I get a undefined method `ajax_scaffold’ for MyJobsController:Class.

  23. @Mark – you would unzip it in vendor/plugins. Scott.

  24. Great Plugin, what if I wanted to display the id next to each entry?

  25. Hi Hesham, to display the id you would need to configure the columns yourself. You can see how to do this in "this post":http://blog.caronsoftware.com/articles/2006/09/05/defining-custom-columns-with-ajax-scaffold-plugin

    Cheers, Scott.

  26. It doesnt works for me. It produces an error:

    TypeError in UsersController#table

    can’t convert nil into String

    Cheers,

    LEo

  27. Hi Leonardo – not sure what that would be. I would try submitting a slightly more verbose version to the "forum":http://groups.google.com/group/ajaxscaffold

    Scott

  28. Hi.

    nice work! but I have a quick and simple question:

    Where do I put the users.rhtml file? I tried to put it into the /views/controller_name, /views/model_name, /views/ajax_scaffold and i always get bland html and errors saying that Rico isn’t available.

    Thanks!

  29. Hi Scott. How can i update some field`s values (like date of creation), which are not displayed by custom _form.rhtml

    PS: Sorry for my dumb question, but i have`t enough patience for reading RoR docs till the last and starting with your great plugin in my app :)

    Leon

  30. @Martin, have you included all the javascript in your headers?

    @Leon, Rails will update any updated_on / updated_at / created_on / created_at fields automagically for you so you don’t have to edit those yourself. If you want your form to contain those fields for hand editing then you will need to define your own custom form.

    Cheers
    Scott.

  31. Thanks for all your customising ajax scaffold which I used a lot.
    But I am facing problems with Ajax scaffold when I use ajax scaffold with salted hash login generator on the same model.
    The login generator uses session[:user] to store the user information for a valid user and ajax scaffold uses the same session variable to store the sort column and the sort direction etc.
    As the session[:user] is used all over along code to check for the valid user it cannot be changed do you have any better solution for the same?
    NAYAK
    (Vishwanath Nayak K)

  32. @Mark : same thing for me, the script/install does not do anyhting.
    I am definitely not behind a firewall.

    - I unzipped under the Vendor/plugins directory
    In my case C:\…\Depot\vendor\plugins\ so that I now have a ajax_scaffold_plugin-3.2.2 folder in it now

    - I reloaded rails, as plugins are loader at boot time

    Now it works… and it is a wonder !!
    Thank you !

  33. @NAYAK – I don’t think there is anything you can do. It would of been a good idea to access the user session through a method then you could change that to access session[:user][:current] or something similar. As it stands I think you will have to change everything or no use the scaffold. Sorry.

    Scott.

  34. I could not get the plugin to install, so I copied
    ajax_scaffold_plugin-3.2.2 directory into \app\vendor\plugins

    I modified the app/controller/user_lanuages_controller.rb adding
    ajax_scaffold :user_language
    to it.
    I created a user_languages.rhtml the contains that is identical to your example users.rhtml file in app/view/user_languages

    All I get is the normal html list when I go to http://localhost:3000/user_languages/

    I read a post up further that sounded similar, and your suggestion was to ensure that the javascript was in all the headers. I am not sure what you mean by that. I followed the instructions at the top and do not see any instructions on javascript.

    Thanks

  35. First off, I wanted to say great job on the plugin, I started out using the generator and switched over as soon as I heard of the plugin. Made life much easier.

    I’ve run into some issues when trying to display multiple tables on the same page. The problem is that the tables are all coming from the same controller (eg Repairs). The Repairs controller has a custom conditions_for_repairs_collection and each of the tables on the page is passing a different id for the condition so that the tables are different.

    I’ve tried with and without suffix and no matter what the id generated for the table seems to always be "repair" which certainly isn’t good to have 10 of the same id. Oddly enough a lot of the tables are actually functional, except for any sort of paging.

    Is there some other means to make each table generated distinct so that they stop interfering with one another?

  36. @4tc.org – this is the line I was talking about: <%= ajax_scaffold_includes %> it needs to go in the header of your page. Sounds like you aren’t getting the css which is the same issue.

    @Rich, you can just create them from different controllers, which is probably the best thing to do anyway with the REST / CRUD thang. The multiple tables from a single controller only works if they are scaffolding different models not if you want 10 repair tables with different contents.

    Scott.

  37. @scott/4tc.org:
    I seem to have the same issue. I followed the sample .rhtml file which should place the javascript includes in the header (right?), and no luck. Like 4tc.org, I was also forced to perform a manual install.. perhaps there’s something I didn’t do correctly?

  38. Yea, creating separate controllers wont really work as it’s a dynamic number of tables being displayed, could be 1, could be 10. I think I’ll just have to switch that section to only display tables as they don’t really need to be able to edit the values directly in that section anyway.

    Thanks for the quick response.

  39. Scott,
    Thanks just to clarify. Here is what I have in the view page.
    <pre><!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml&quot; lang="en">
    <%= javascript_include_tag :defaults %>
    <head>
    <%= ajax_scaffold_includes %>
    <h1>Listing user_types</h1>
    </head>
    <body>

    <%= @content_for_layout %>

    </body>
    </html>
    </pre>
    And Controller
    <pre>class UserTypesController < ApplicationController
    ajax_scaffold :user_type
    end</pre>

    Thanks

  40. I get the following error

    undefined method `ajax_scaffold’ for CategoriesController:Class

    when I run it.

    I have two other classes with generated ajax_scaffold that work (and still work after I installed the plugin). I know all the plugin code is in the right place as I can see it.

    I Did create the layout file with the includes. I tried putting in under

    ../views/layouts where I think it should go

    and also under

    ../views/categories

    this is my categories_controller.rb file

    class CategoriesController < ApplicationController
    ajax_scaffold :category
    def index
    end
    end

    I tried with and without the def index, but as you can tell it does not get that far anyway

    thanks

    Jeff

  41. ok, I got it to work by putting:

    require ‘ajax_scaffold’

    in my model

    I didn’t see that this was required in the tutorial, is it supposed to be?
    Or is it picking up something from the generater version?

  42. I’m running against SQL Server and I’m getting this error.

    DBI::DatabaseError: Execute
    OLE error code:80040E14 in Microsoft OLE DB Provider for SQL Server
    The column prefix ‘clients’ does not match with a table name or alias name used in the query.
    HRESULT error code:0×80020009
    Exception occurred.: SELECT * FROM (SELECT TOP 1 * FROM (SELECT TOP 1 * FROM clients ORDER BY clients.id asc ) AS tmp1 ORDER BY clients.id DESC) AS tmp2 ORDER BY clients.id asc

    The sql statement isn’t valid if I take it out and put it in Query Analyzer I replaced clients with tmp1 and tmp2 where appropriate and the query ran. I’m using the generator, any help would be appreciated.

  43. Hi David,

    Can’t really help you there I’m afraid, no real experience of MS SQL, although it sounds like an Active Record bug in the generation of the SQL. You are best off asking generator (which is now deprecated by the way) questions on the "forum":http://ajaxscaffold.stikipad.com.

    Cheers
    Scott.

  44. This is superb! I just followed your example and had this running in under five minutes. I’ll have to step back and reconsider some (much more difficult) things I was attempting via "straight rails". Thank you!

  45. I have a patch that adds a prefix to the scaffold_id, making ajax_scaffold play friendly with login_generator.

    I had to change default_scaffold_id to:

    :default_scaffold_id => "ajax_scaffold_#{singular_name}"

    As well as a couple other changes to support this, but it all seems to be working now. And it doesn’t get cloberred by login_generator. How should I submit the patch?

    Ryan

  46. Hi Ryan, probably the best thing to do is post the fix on the forum, then people using the current version can use it. The latest version of the plugin changes things a lot, so any patch will no longer be applicable.

    Thanks.
    Scott.

  47. Hay hay
    Well nice plugin. But there is a little problem at my hack. May be I forgot something to do?

    The List Action runs wuiet right (Table looks good), but if I press one of the Edit Buttons, there will be an error:

    RJS error:

    Could not convert JavaScript argument" nsresult: ….
    NS_ERROR_XPC_BAD_CONVERT_JS location JS Frame ../javascripts/prototype.js?… line 1206 data: no

    If I press the okay button another modal window is opened with a lot of HTML Output is shown. It is too long to view at the end.

    And after that the line I wanted to edit is hidden in the table. After a refresh it is shown quiet right.

    Any ideas whats going wrong here ?

    bye

  48. I’m trying to use ajax scaffold plugin with Rail 1.2.1 and I keep getting errors.

    Maybe materials given is not a valid Ruby identifier?
    (eval):1:in `evaluate_read_method’: compile error
    (eval):1: parse error, unexpected tFID, expecting ‘\n’ or ‘;’
    def materials given?; query_attribute(‘materials given’); end
    ^
    (eval):1: parse error, unexpected kEND, expecting $
    def materials given?; query_attribute(‘materials given’); end

    Any ideas?

  49. Solvation:

    I used the application.rhtml for corporate design of all other rhtml pages at the view/layouts directory. That was a bad idea and the problem in my app. Dont know really why, but in my opinion the access via DOM is different for every page …

    bye

  50. Does this plugin work with Rails 1.2.1/Prototype 1.5? I can get the table to display, but clicking any of the actions just leads to the spinner spinning forever and no request showing up in the log.

    Any thoughts?

    Thanks.

Sorry, the comment form is closed at this time.