In my previous post about Rails and Engines, I talked about some of the issues I’d like to see resolved in Rails 2.0. Specifically, it seems that we need to rethink modularization in Rails and make it easier for people to share complete slices of applications.
One of the primary hinderances of the present Rails architecture to modularization is the directory structure.
Consider the typical rails app directory:
app/ controllers/ application.rb account_controller.rb blog_controller.rb comments_controller.rb helpers/ application_helper.rb account_helper.rb blog_helper.rb models/ user.rb blog.rb post.rb comment.rb views/ account/ signup.rhtml login.rhtml edit.rhtml blog/ index.rhtml archive.rhtml post.rhtml comments/ view.rhtml remove.rhtml layouts/ application.rhtml
Now at first glance, the Rails directory structure seems quite helpful. There is a place for everything and everything is in its place. Models go here, views here, controllers here… The entire MVC in 3 different directories. Wait a minute! Compare this to the Django directory structure for the same application:
account/ __init__.py urls.py models.py views.py templates/ account/ account_login.html account_signup.html account_edit.html blog/ __init__.py urls.py models.py views.py templates/ blog/ blog_list.html blog_archive.html blog_detail.html comment/ comment_view.html comment_remove.html
Wow! See the difference? Django divides the application up not according to file type, but according to logical structure. Related files are together. This makes it easy to share entire chunks of an application. All you have to do is create an svn:external to the appropriate directory of another app and instantly you have access to an entire slice of the other application.
Imagine if Rails took the same approach. The new app directory could look something like this:
app/ application/ application_controller.rb application_layout.rhtml account/ _config.rb _routes.rb account_controller.rb account_helper.rb account_edit.rhtml account_login.rhtml account_signup.rhtml user.rb user_migrations.rb blog/ _config.rb _routes.rb blog_controller.rb blog_helper.rb blog_index.rhtml blog_archive.rhtml blog_post.rhtml comment.rb comment_migrations.rb comments_controller.rb comments_helper.rb comments_view.rhtml post.rb post_migrations.rb
Now I've changed things around just a bit to accommodate the new directory structure and support better modularization. Views are now prefixed with the name of the controller that they are associated with (this allows us to avoid having to put them in a separate directory). I've also changed migrations around so that all the migrations for a particular model are in the same file (we would probably need a new domain language for this). Also note that the _config.rb and _routes.rb files give us a convenient place to store configuration for a particular slice of our application (the underscore prefix would sort them to the top of a directory listing).
So that’s my big idea for Rails 2.0. It would be a radical departure from the present directory structure. So radical that it would effectively make Rails 2.0 applications incompatible with Rails 1.0 apps. But we are already dropping support for deprecated features in Rails 2.0, so perhaps it’s time to rethink the directory structure.
Update: There is some interesting discussion going on about this on the Rails-Core mailing list.
© 2013 John W. Long