I been workin’ on the Rails road
Our fourth son was born last week. While we were still in the hospital I managed to put the finishing touches on a contribution to an open-source project. I submitted my first patch for Ruby on Rails. The core team has yet either to apply or reject my patch, but in the meantime I started an open-source project of my own that takes the work even further. The project is called Trestle.
The trestle generator is an adaption of the built-in Rails scaffold generator whose function is to build temporary web pages for maintaining database tables. The scaffold generator is great but there are two things that bother me about it:
- Scaffolding fails to protect itself against errant HTTP GET requests (such as come from Google Web Accelerator and the like)
- Scaffolding is overly complex—there are eight actions to support the four activities of creating, reading, updating, and deleting records (affectionately known as CRUD to database application developers)
The first item is a real problem. Rails scaffolding is not intended to serve as production code. It’s a convenience for developers while they build out web applications. In reality, though, a good number of Rails applications in production probably leave much of the scaffolding in place and therefore maintain the vulnerabilities that it introduces. Don’t drive a train across a gorge with nothing but a scaffold underneath; build a trestle instead!
The second item is more a question of taste.
| Scaffold | Trestle | ||
|---|---|---|---|
| URL | Remarks | URL | Remarks |
| /people | Lists existing Person objects | /people | Lists existing Person objects |
| /people/list | Lists existing Person objects | ||
| /people/new | Shows an empty form for a Person object | /people/new | Shows an empty form for a Person object |
| /people/create | Creates a new Person object from request parameters | On postback, creates a new Person object from request parameters | |
| /people/show/99 | Shows the Person object having ID 99 | /people/99 | Shows the Person object having ID 99 |
| /people/edit/99 | Shows a form for the Person object having ID 99 | /people/99/edit | Shows a form for the Person object having ID 99 |
| /people/update/99 | Updates the Person object having ID 99 using request parameters | On postback, updates the Person object having ID 99 using request parameters | |
| /people/destroy/99 | Destroys the Person object having ID 99 | /people/99/destroy | Redirects to /people/99/edit with a notice that the user must click the form’s Destroy button in order to destroy the object |
| On postback, destroys the Person object having ID 99 | |||
Tobias Lütke’s postback_generator RubyGem has the same idea about enforcing the use of HTTP POST for state-changing operations (the C, U and D of CRUD). But notice the hierarchical nature of trestle URLs. A URL that ends with “/controller[/99][/action]” allows users to click the Up One Level button on the Google Toolbar to explore an application. Up One Level clips the last element off the end of the web address displayed in the browser’s location bar. Scaffold URLs don’t play
nicely with the Up One Level button.
The trestle generator improves on scaffolding in other ways, too, such as giving the user a friendly message if his request is missing an ID.
If you’re already riding the Rails then getting hold of the latest version of my trestle generator is easy as pie. Type the following at the command line:
gem install trestle_generator
After the trestle_generator RubyGem is installed, try using it just as you already do Rails’s scaffold generator. Assume you have a table called people in the database behind your Rails application. From the root directory of your Rails application type:
./script/generate trestle Person
Enjoy! 
Congratulations!! We rejoice with you over God’s good gift of a 4th son.
Great work!, and congrats!
Would it be very difficult to extend trestle to provide a ‘parent select’ select box for models that ‘belong_to’ another model? (i’m guessing it might be since there don’t seem to be any generators around that do this already).
Yes, I’ve been considering this kind of thing as an extension to the trestle generator. What I had in mind was command-line options that would allow the developer to specify belongs_to, has_many, has_and_belongs_to_many, and has_one relationships. This would make it possible to generate pick-lists for related objects in the views. It would also make it possible to refactor actions to more appropriate controllers.
Consider:
We could generate controllers that respond to the following URLs. Notice that the “list” and “new” actions for BlogComment have been moved to the BlogPost controller.
/blog_posts
/blog_posts/new
/blog_posts/123
/blog_posts/123/edit
/blog_posts/123/update
/blog_posts/123/delete
/blog_posts/123/blog_comments
/blog_posts/123/new_blog_comment
/blog_comments/789
/blog_comments/789/edit
/blog_comments/789/update
/blog_comments/789/delete
But this is going to take a whole lot more work than I’ve put into the entire project thus far.
[…] I submitted another Rails patch the other day and this evening the mighty bitsweat committed it. I’m officially a Rails contributor! Aw yeeah! (does dorky victory dance) […]
[…] Gem trestle_generator Un generateur scaffold qui propose quelques variantes pour pouvoir ĂŞtre utilisĂ© en production. (tags: rails scaffold) […]