Announcing: Ext Scaffold Generator Plugin for Rails

January 18th, 2008

Ext Scaffold Generator Plugin GUI Screenshot.pngThe Ext Scaffold Generator Plugin can be viewed as a drop-in replacement for Rails’ standard Resource Generator. Accepting the very same options, it will generate views using data grid and form components from the Ext JS Javascript GUI framework as well as a controller acting as an Ext-compatible JSON web service. The generated code can be used as a starting point for further implementation and outlines solutions on how to integrate the Ext JS library with Rails as a backend.

What it does not do

Ext JS is huge. It provides just about any component for developing Rich Internet Applications. The Ext Scaffold generator only uses a very limited subset of Ext JS. It includes some view helper methods to generate Javascript code, but these helpers are not really meant to be used in other contexts. IMHO it is better to code the Javascript in views by hand.

Any attempt of providing helpers for even a subset of the Ext functionality seemed like a dead-end approach to me. For further refinement of your application I suggest looking at the generated JS code and change it to suit your needs.

Features and Concepts

The way Ext JS works is to code all GUI components and interactions in Javascript. These components will then interact with a datastore backend via web service requests (either JSON or XML formatted).

The Ext Scaffold Generator Plugin provides a custom MIME type alias :ext_json to be able to handle requests from the Ext frontend separately. The generated controllers show how to do this.

To make data delivery to the Ext frontend easy, the plugin extends the Array and ActiveRecord::Base classes to provide a to_ext_json method. Here’s a simplified example of a potential index method in a PostsController:

# GET /posts
# GET /posts.ext_json
def index
  respond_to do |format|
    format.html     # index.html.erb (will fire ext_json request)
    format.ext_json { render :json => Post.find(:all).to_ext_json }
  end
end

to_ext_json will also format validation error messages attached to ActiveRecord::Base objects. This can be used to provide server-side validations additionally to Ext’s own client-side validation features in forms. Another simplified example using our fictitious Post resource:

# Model
class Post < ActiveRecord::Base
  validates_presence_of :title
end

# Controller
class PostsController < ApplicationController
# ...
# POST /posts
  def create
    @post = Post.new(params[:post])
    if @post.save
      flash[:notice] = 'Post was successfully created.'
      render(:update) {|page| page.redirect_to posts_url }
    else
      render :json => @post.to_ext_json(:success => false)
  end
end
# …
end

Installation

script/plugin install http://rug-b.rubyforge.org/svn/ext_scaffold

After the plugin has been installed, download the Ext Javascript framework from http://extjs.com/download and unzip it into #{RAILS_ROOT}/public/ext. The plugin was tested against version 2.0.1 of the Ext framework.

Usage Exmples (call without params for help)

./script/generate ext_scaffold post title:string body:text published:boolean
./script/generate ext_scaffold purchase order_id:integer amount:decimal

Recommend Martin Rehfeld on Working With RailsIf you like this plugin, please consider recommending me on Working with Rails. Thank you!

Related Posts

Entry Filed under: Tools, Announcements, Ruby on Rails, Ext JS

47 Comments Add your own

1. Tim  |  January 19th, 2008 at 9:10 pm

Is there a simple way to change the width of the extjs grid?
Or to make it the same width as the enclosing window?

2. martin.rehfeld  |  January 19th, 2008 at 9:15 pm

Yes, there is: The ext_grid_for helper takes additional options, allowing you to specify :height, :width, :title and a couple more. You can modifiy the index view accordingly.

3. Jonathan  |  January 22nd, 2008 at 7:31 pm

How do you set initial pagination? I have a table with 150k records in it and when I tried to use the basic ext generated view, it appeared to try to load all 150k in before it displayed….I had to kill the process, as I didn’t want to wait that long… ;-)

4. martin.rehfeld  |  January 22nd, 2008 at 7:38 pm

@Jonathan/#3: Yeah, I got a similar report the other day. The session does not seem to initialized correctly. I will take a look at it soon.

5. Alex Rodriguez  |  January 22nd, 2008 at 8:36 pm

Great work, congratulations.
Some questions. Exists the way to use combo boxes like to:
http://extjs.com/deploy/dev/examples/form/combos.html
Can be used radio buttons in the forms ?
In your pdf presentacion you write about menus and tabs. You are going to offer the possibility
to use tabpanels in the forms?

6. martin.rehfeld  |  January 22nd, 2008 at 10:37 pm

@Jonathan/#3,4: The pagination error should be fixed now, please re-install the plugin using script/plugin install http://rug-b.rubyforge.org/svn/ext_scaffold --force

7. martin.rehfeld  |  January 22nd, 2008 at 10:47 pm

@Alex/#5: The features you are referring to can be coded quite simply using Ext JS but are beyond the scope of the scaffold generator. Ext has a very complete API reference and the combo box example you linked to can be incorporated into the new/edit views fairly easy as well. As stated above, it’s probably best to look at the JS that gets generated, copy that into your custom views and hand-code from that point on.

8. Alex Rodriguez  |  January 22nd, 2008 at 11:58 pm

This plugin works with Rails 1.2.3 ?
After to install in the generate ext_scaffold appears many errors.
Or is only for Rails 2.0 ?

9. martin.rehfeld  |  January 23rd, 2008 at 12:00 am

@Alex/#8: It’s Rails 2 only!

10. Jonathan  |  January 23rd, 2008 at 3:54 am

ok, that fix appears to have worked for the pagination issue. Although I am now running into another strangeness…

I am trying to integrate this with a legacy db, The model is a Lead model, but the row id is lead_id instead of the standard AR ‘id’. I have the model configured correctly using the set_primary_key “lead_id”, but when it is collected in the grid view, the id field is blank and when I click on a row to edit, I get an error, since it is offering a lead if like 1004 (when the lead_ids are actually up in the 50899 range). s there somewhere I need to set it in ext or in ext_scaffold to use the lead_id field? I tried to define:

def id
self.led_id
end

in the lead model, but that didn’t help…

11. Mark Buckingham  |  January 23rd, 2008 at 3:59 am

Hi- I tried the posts example above, and it works really well. I noticed one weird thing though… When I create a new post and click save, it goes back to the list view. For some reason, the posts don’t show up again unless I click on one of the columns to sort. Am I doing something wrong?

Oh- And this is very cool. Thanks for putting out there!

12. martin.rehfeld  |  January 23rd, 2008 at 11:33 am

@Jonathan/#10: You have to tell Ext’s JSONReader about your primary key as well. Something like this will do:

var lead_datastore = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: '/leads?format=ext_json',
method: 'GET'
}),
reader: new Ext.data.JsonReader({
root: 'leads',
id: 'lead_id',
totalProperty: 'results'
},
[ {name: 'id', mapping: 'lead_id'}, {...} ])
});

I updated the View helper to pick up the primary key column automatically. So maybe it will work for you out of the box now.

13. feiichi  |  January 23rd, 2008 at 4:56 pm

Hi,
I love it! Great job..

14. Samir  |  January 23rd, 2008 at 5:14 pm

Amazing job Martin, is very nice!

15. Tim  |  January 24th, 2008 at 1:36 am

I agree, it is very nice.

But I’m totally stumped by how to get a “Search” widget to work with the Rails “backend”. Can anyone post a little sample code showing an extjs “Search” widget that can find certain ActiveRecords?

TIA !!

16. martin.rehfeld  |  January 25th, 2008 at 1:08 am

I just updated ext_scaffold to fully support and recommend Ext 2.0.1 - as the current implementation caused trouble, I replaced the DateTime picker with a new version. Give it a spin and let me know how you like it.

17. Joerg Battermann  |  January 26th, 2008 at 12:01 am

Hey there - awesome work!! :)

Quick Q: have you successfully used the extjs treeview with a rails backend (acts_as_nested_set and the like)?

18. martin.rehfeld  |  January 26th, 2008 at 12:18 pm

@Joerg/#17: Sure, using Ext.tree with a Rails backend works very well. I will summarize the steps neccessary in a separate post - should be online this weekend :-)

19. Joerg Battermann  |  January 26th, 2008 at 12:59 pm

Awesome! Thanks :)

20. martin.rehfeld  |  January 26th, 2008 at 6:47 pm

FYI: The tutorial on how to use Ext Tree with Ruby on Rails is now online.

21. Dom  |  January 27th, 2008 at 4:23 pm

Love your work- thanks heaps…

Any chance you can make this generator “namespace-friendly”?

I’ve found that the model file needs to be moved up into the models folder and have the namespace removed from it’s name, and the migration needs to be edited to remove the namespace from the name of the table. However, even after doing this, the urls generated in the view templates are incorrect and do not include the namespace, consequently when clicking the New and Edit buttons in the index result in a page not found error.

22. martin.rehfeld  |  January 27th, 2008 at 4:43 pm

@Dom/#21: Good catch.

23. OutThere  |  January 28th, 2008 at 4:32 am

Don’t know how to build task ‘migrate’…
I had a look at migration files and they seem ok, except that they have a different sysntax…

I’d write:
t.column :title, :string
But it looks like
t.string :title

Needless to say, I get an error while reading from DB… :)
What gives?

24. martin.rehfeld  |  January 28th, 2008 at 11:19 am

@#23: The migration syntax used was introduced with Rails 2.0 (usually referred to as Sexy Migrations, yeah ;-) ). Generally speaking, the Ext Scaffold Generator will only work with Rails 2.x.

25. Tomek.C  |  January 28th, 2008 at 6:22 pm

Nice job! But isn’t possible to set desired controller name? I’d like to have “admin/users.rb” controller, for example.

26. martin.rehfeld  |  January 29th, 2008 at 10:15 pm

As pointed out in comment #21, namespaced resources are currently somewhat unsupported.

27. ryan o  |  January 30th, 2008 at 9:29 pm

Anyone figure out how to add a search funciton?

28. seairy  |  February 1st, 2008 at 5:21 am

This is a great plugin, but i have a question: how can i create a select field? for instance, i have a model named “document”, and another named “category”, then i want to have a select tag for “category” in new/edit document rhtml,how to do that?

29. martin.rehfeld  |  February 2nd, 2008 at 5:30 pm

Ext Search Field in Grid@Tim/#15,Ryan/#27: I just decided to include a sample search field in the grid and show how to wire it to ActiveRecord - credit for the grid plugin goes to Saki! The magic within the Ext Scaffold Plugin is performed in ActionController#options_from_search (to be found in plugins / ext_scaffold / lib / ext_scaffold_core_extensions / action_controller / base.rb)

30. martin.rehfeld  |  February 2nd, 2008 at 10:56 pm

@seairy/#28, Alex/#5: Be sure to check out the new mini-tutorial on using Ext.form.ComboBox with Rails.

31. Ian  |  February 7th, 2008 at 6:25 pm

Neat!

One problem though, if I have a model for a legacy DB that uses alias_attribute then it doesn’t seem to work in the ColumnModel. That is, if I has alias_attribute 'name', 'CATEGORY_NAME' in my model I still have to use category[CATEGORY_NAME] in the view code.

Any ideas?

Also: a suggestion - if no height or width are specified in ext_grid_for it should default to auto, the same as the normal EXTJS widget does (in my opinion, anyway).

32. martin.rehfeld  |  February 8th, 2008 at 1:14 am

@Ian/#31: alias_attribute just gives you additional getter/setter for your model. It does not instruct Rails to prefer the alias over the native attribute. YourModel.attribute_names will still list only the native attributes, not the aliased ones.

So, if you want to use your alias in the view, you will also have to code the Ext Datastore definition manually (instead of using the ext_datastore_for :your_model helper).

Setting width/height to auto seems reasonable. I’ll look into it.

33. Ian  |  February 8th, 2008 at 6:52 pm

OK, thanks, ext_datastore_for doesn’t look too onerous to replace.

Cheers,
Ian.

34. CLR  |  February 22nd, 2008 at 5:29 pm

Martin, this plugin is smooth like liquid Amon Tobin on a hot Summer day. I am using some of the other ext_ widgets as well. Are you open to collaborate on more generators?

35. Sergey  |  February 28th, 2008 at 6:41 am

Martin, I just tried “Advanced Ext JS Form Controls with Ruby on Rails: ComboBox” example and it works perfect. Now I wanted to show this new Category.name in the grid and I am kinda lost. Is it possible to do?

Thanks

36. CarmineM  |  February 28th, 2008 at 7:33 am

Hi Martin,
first off thanks again for this useful plugin.

I have a model which has some calculated fields, hence not present in the migration and the table. What happens is that even if I generate manually the grid to display table’s records, the “to_ext_json” doesn’t pass those calculated fields to the grid.
I poke in the “to_ext_json” code and saw it uses “attributes” to fetch the fields of the model.
Attributes doesn’t return also the calculated fields. Is there a way to accomplish this without touching “to_ext_json” code?

Thanks for your help

37. martin.rehfeld  |  February 28th, 2008 at 9:18 am

@Sergey#35/Carmine#36: There is work in progress to let you specify additional attributes in your model to be included in to_ext_json. Until that is available, you would have to hand-code your data store definition and column model, I’m afraid.

38. Kanst  |  February 29th, 2008 at 11:45 am

Just want to point out that you need to consider calculated fields when generating JSON with error messages (model.to_ext_json(:success => false)). As for now you can replace

attributes.each do |field, value|
if errors = self.errors.on(field)
…..

with

errors.each do |e|
….

in base.rb

That works for me :)

39. Marcus Westin  |  February 29th, 2008 at 9:48 pm

Hey,

I wrote a script to automate installation and sample setup of your plugin.

Please add it to the post if you think people will find it useful to get up and running.

Thanks for the good work!

40. bioform  |  May 20th, 2008 at 10:47 pm

Does anybody have ideas how to create and edit objects from grid in a pop up window ?

41. bioform  |  May 20th, 2008 at 11:16 pm

And one more…
I’ve just found that some columns are not sortable… for example columns with “desc” and “from” names

42. Someone Random  |  June 3rd, 2008 at 6:54 pm

You should take out the helpers completely. Have your scaffold plugin generate real JS and real tags. Your plugin was what exposed me to the world of JS UI libraries, so I thank you, but figuring out how ExtJS was also extremely difficult thanks to your library because the helpers obfuscated the underlying concept behind this library, which is JSON. Again, however, your plug-in did a lot for me and probably many other Rails developers in introducing them to this concept.

43. martin.rehfeld  |  June 3rd, 2008 at 7:01 pm

@42: You’re probably right. People tend to overrate the helpers and get frustrated when they discover that sooner or later handcoded JS code is inevitable.

44. Berthor  |  June 3rd, 2008 at 9:15 pm

with rails 2.0.991 there is now 4 new default, and one of them is ActiveRecord::Base.include_root_in_json = true. which in turn will break the extjs because now the json isn’t formatted right. just change that to a false and from what I see, it works.

cheers

45. Sam M.  |  June 19th, 2008 at 8:57 pm

I ran into a problem with ext_scaffold and extjs 2.1. I kept getting a blank screen while trying to go through the Post demo where Ext.ux.grid was reported to have no properties. It appears to be a problem with how I installed ext_scaffold, mainly I copied the plugin into my rails project and didn’t use script/plugin to do it, so the install.rb wasn’t run. This left out some important files like ext_datetime.js and ext_searchfield.js from getting copied into my rails public/ directory. I found a blog post that explained how to fix this here:
http://www.42.mach7x.com/2008/04/23/extuxgrid-has-no-properties-error

46. Pontus  |  August 6th, 2008 at 12:43 am

Just wanted to elaborate on Berthors post @44. I’m using 2.1.0 and I followed the example given above, but did not get any data in the grid. The problem is the json formatting.

The following links should be helpful:

http://www.extjswithrails.com/2008/05/more-rails-21-that-target-json-and.html

http://www.akitaonrails.com/2008/5/25/rolling-with-rails-2-1-the-first-full-tutorial-part-1

47. Vincent Jacquel  |  September 29th, 2008 at 1:58 pm

Just wanted to precise post number 2 : The syntax for the additional options for the helper is the following :

‘incorrect_bill-grid’ , :width => 800, :height => 400, :page_size => 15, :force_fit => true , :stripe_rows => true, :title => ‘List of incorrect invoices’ %>

this shows an example using width, height, page size, force fit, stripe rows and title parameters and extends the original grid created by the plugin to something closer to real life situation.

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed




You are viewing a mobilized version of this site...
View original page here

Mobilized by Mowser Mowser