Adventures in Rails and Django (contains comparisons, but isn't a Vs. topic)

NuvoNuvo Forum LeaderVPS - Virtual Prince of the Server
WARNING: Do not read, this is too long, especially for Daniel Nerri, who will post "Too long, might read later or something".
This is not an x versus Y topic by the way!

Hello.

If you're into developing web sites, you've no doubt heard of Ruby on Rails and the whole web application framework movement that's been going on a lot recently.
I've been building a CMS style app with Rails for a while, and it's pretty much stopped me working with raw PHP for a number of reasons.

The other big names in web frameworks are CAKE, Symphony, TRAX and Django.
CAKE, Symphony and TRAX are all PHP frameworks and some, like TRAX, are an attempt to port Rails to PHP.
Django is a fairly old framework for Python, which has recently been released as an Open Source project (previously, it was used for sites by Lawrence Journal-world).
PHP isn't a completely evil language by any means, but it lacks a lot of what Python and Ruby have as it's not as robust in terms of OOP support and it's mainly designed for scripting.

What makes Django and Rails so interesting is the level of object orientation in the code and the number of non-web specific libraries which can be used with them (such as CodeRay for Ruby).

I decided, after running into a bit of a wall with my Rails app (pretty much got over this though with a little mod to some code I wrote), that I would look into Django, which is fairly different to Rails, but has many of the same goals.
This is what I found.

MVC, MTV, CNN?
Rails follows MVC pretty well.
MVC stands for Model View Controller, and it's a way of breaking an app down into database interaction, application logic and templating.
A Model basically looks at your database to find data as well as handling saving to the database and modification.
A View is basically a template that your app puts data into.
Think of it like building a template for a blogging app...
You'd have a tag which tells the blog where to put blog entries or comments.
A Controller holds the logic of your app, meaning that if you wanted to grab something from the database, you'd put the code to do it in here.

Django has a different way of doing exactly the same thing.
With Django, Views hold logic, Models are for database interactivity and Templates are exactly what they sound like, templates.

Where am I going and where did I come from?
Both frameworks have inbuilt routing systems.
This basically means that you don't need to play (or fight) with Apache's mod_rewrite to get pretty URL's.
Rails uses routes.rb while Django has urls.py.

Rails' approach to this is straight forward and understandable as:
# Correct all the actions and such for the publicly accessable part of the site to make it work.
   map.connect ':action/:id', :controller => 'blog'
Means that the user should be sent to ":action/:id", which is in the blog controller when they go to site.com/show/123.
:action is a block of code you've created, much like a function so "site.com/show/123" would run the "show" code block.
:id is just a variable passed on the end of the URL, so "site.com/show/123" would run "show" to get the 123rd entry in the database.
The reason for them looking all weird with the colon is that they are reprisented by symbols.
A symbol is something you run into a fair bit in Rails as they are used when working with different actions (the code blocks) and with variables passed by forms and query strings (which you should never see in either of these frameworks as they make pretty URL's).

Django is somewhat more complex as it doesn't have the happy bunnies and magical rainbows of Rails.
As I worked through the tutorial on the Django site, I found myself writing multiple documents to handle URL's due to the tutorial going on about decoupling applications for ease of portability (explained later).
The URL's I've ended up with look something like:
# In the main urls.py file:
(r'^polls/',  include('firstapp.polls.urls')),

# In my apps offshoot urls.py:
(r'^(?P<poll_id>\d+)/results/$', 'results'),
While it's not "YOU MAKE BUNNY CRY!" level complexity and there's easier ways of doing it (they don't tell you this until later), it's still less readable than routes.
Basically, it's saying that if if the URL starts with something like site.com/polls, it should look in my offshoot.
The offshoot then looks to see what else is going on in the URL, such as site.com/polls/1/results/ and it'll run the code for whatever it finds.
Django is more REGEX intensive than Rails, but that's not always a bad thing (learning preg_replace() in PHP made me a happy bunny) and it still beats having to configure mod_rewrite all the time (because this is distrobuted with the application).

A language for everything and a language for templates!
If you've ever had to build a dynamic website before where other people will want to change something without really understanding the complex web of interweb development that you have in place, you'll no doubt have come to know the evil charms of the template engine.
Rails doesnt have one of these, it just uses Ruby code mixed with XHTML.
That may sound scary, but since you don't need some monolithic block of bloated code that's going to be sucking in external resources and which will break if you even think about thinking about looking at it (hello bad PHP programmers), it's not that bad.
Also, Rails comes with a load of happy little helpers which allow you to hook in CSS files, images, forms and other commonly used things, so you don't always have to type out XHTML tags (Rails outputs XHTML by default, so using these helpers can be handy if you aren't an XHTML ninja like me :D).

Django goes as far the other way as it can.
Rather than sticking with some form of embeded Python, we get a full blown template language.
While this isn't required (you can use other templating systems apparently, or none at all), it's pretty nice to have if you're passing basic templates to a designer and shouting "MAKE PRETTY THINGS!!" in binary or something.

In fact, there's a plugin for Rails called Liquid, which basically adds Django \ Smarty style templating support, but secured enough to stop some newbie from nuking things.
This is what I had hoped to use in CMS Object, but it seems to hate me for some reason.

All your database are belong to us!
Both of these frameworks run with a number of SQL compatible database systems.
Django rund with Postgres, mySQL and SQLite right now, but more are planned.
Rails supports MySQL, PostgreSQL, SQLite, Oracle, SQL Server, DB2, or Firebird, but apparently, some can cause it to crawl a bit, so Postgres, mySQL and SQLite are your best bets.
Both have some form of non-SQL database interaction (you write some code and the framework does the SQL for you) and both let you get dirty when needed.

Rails uses syntax like:
something = Thing.find_by_genericfield(params[:id])
Which would get the I.D. from the URL in order to search the "things" table's "genericfield" column.
Rails supports "Model.find(parameters)", "Model.find_by_field(field and parameters)" and "Model.find_by_sql(query)" forms of searching where "Model" is the model for the table (usually something like "Comment" for comments or "User" for users) and parameters can be what to look for and conditions to fine tune the search.

Django's syntax is more like:
p = get_object_or_404(Poll, pk=poll_id)
Where get_object_or_404 either gets what you need, or shows a "not found" error and "pk" is the I.D. to look up.
The problem here is that "get_object_or_404" and the "Poll" model aren't available by default, you have to include them with:
from django.shortcuts import render_to_response, get_object_or_404
from firstapp.polls.models import Poll
The Django tutorial does claim that you can cut some of this out though by changing the routing code, but I prefer to keep URL and application logic in their own place.

Code everything vs code something...
Rails has a feature called scaffold, which looks at the database tables and builds basic CRUD interfaces for you.
This is great when staring out, but eventually you will want to expand and improve and Rails allows you to do that and it'll even give you the code it's built for you so that you can work from it rather than using the scaffold command in controllers.
What Rails doesn't do is take the boring job of building an admin system out of it.
While it's not exactly hard work to get an admin system off the ground in Rails, and you can do some neat stuff with the AJAX helpers (functions which make you less suicidal when using web 2.0 interfaces), it's still not the greatest task to get stuck with while Billy is off coding some fancy front-end that he'll get credit for while you're fixing his mind cripplingly bad HTML.

Django doesn't, as far as I have seen, go out of it's way to give you generic starting code.
This means a little more on your part, but the templating language should make templating pretty simple.
What Django does offer you, it a fully functioning admin system from the start (YAY!).
This comes with a few basic things, but can easily be extended with a little code.
You can modify this ACP by editing it's templates (using the same templating language), CSS and images.
The ACP allows you to add functionality by passing it Models.
Once it's been passed a Model, it can work out (similar to Rails) what table is like and what to build from it, so adding a poll manager is as simple as passing in the Poll model by editing models.py (we'll be mentioning this again).
You can edit how things are displayed as well by changing the order and display mode of elements built from the model within the page.
Django's inbuilt ACP is actually really nice and pretty good on the validation front (I'm getting no hint of code problems) despite having some JavaScript powered abilities such as time selectors and calendars.

Generations ahead
Rails and Django can both create code for you.
In Rails, it has commands like:
ruby script/generate model User
Which create the code required to carry out different tasks.
Django can also carry out some tasks using it's manage.py file, but I haven't delved into this much as of yet.
Rails can generate models, controllers, scaffolding code and other stuff and it's extensible, so people can write generators for other things, and the often do.
On top of that, there's rake, a Ruby make style util, but I haven't needed it as much just yet (it's mostly used for database migration and stats).
Unlike Rails, Django doesn't have different files for it's Models and they aren't virtually empty auto-generated files that descend from some big database pack.
Django has one model file containing model classes that descend from said big database interaction pack per application, and you'll find yourself putting things in them if you follow the Django tutorial, much more than in a Rails model (which is mostly validation code).
It's understandable why it does this though, and that's what we'll move onto next.

Plugins, gems, engines, micro-apps and all manner of chocolatey goodness!
Both of these frameworks can be extended.
Rails has bolt on's in the form of GEM's, engines and plugins.
A GEM is a Ruby package that extends Ruby itself, not just your application.
The advantage of this is that they can be used in any Ruby app once Rails has them installed (doesn't habe to be Rails).
The problem is that since they don't install to your application, anyone without them on their Ruby install is going to have problems.
You can get around this by extracting the GEM into your application though, so it's not a case of dodging GEM's where possible.

Engines and Plugins are installed to your application and only extend the application they are installed into.
Some do have dependancies on GEM files, but if you extract the GEM to your application, this shouldn't be an issue.

Django has applications, though it may be more accurate to call them something similar to micro-applications.
These don't make up an entire site on their own, but can be plugged into any Django site you're working on in order to extend it.
Django applications are pretty much self contained and can have their own routing and such.
If coded correctly, apps can be plugged into the admin interface to further extend it's abilities.
The Django tutorial has you building a poll application which can be used across many sites and which hooks into the ACP to allow it to create and manage polls.

IMHO
I think both are great frameworks that offer much of the same, but have a lot of differences.
Neither is a clone of the other and both have been shown to work in production environments.
My only gripe has been that Python isn't always as elegant as Ruby for this kind of thing and Pyton's indentation based method of programming plays havok with SciTE (if you don't watch where your indents are, Python cries).
I can see the reasoning for offering a templating language nad avoidng it as it's harder for a non-programmer to understand programming code, but it's also annoying to learn one language to make the site work and another to actually put things on screen (and if you don't know HTML, you're in even deeper as you'd need to learn HTML, the programming language and the template language).
Templating is often required though as not everyone knows how to code and sometimes you just want to lock people into having access to a preset amount of functionality (you don't want someone writing a site template that will run a piece of code designed to destroy your app or some required files now, do you?).
PHP, CSS, XHTML, Delphi, Ruby on Rails & more.
Current project: CMS Object.
Most recent change: Theme support is up and running... So long as I use my theme resource loaders instead of that in the Rails plug-in.
Release date: NEVER!!!

Comments

  • DeluxeNamesDeluxeNames Admin Administrator
    Nuvo, this is a fantastic post, thanks for writing this. I don't know why I didn't see this before but somehow I missed it.

    I've just submitted this to Digg because I think it's that good:
    http://digg.com/programming/Adventures_in_Ruby_On_Rails_and_Django_Comparing_Rails_to_Django

    Nuvo, would you consider writing a post that concludes with your favorite PHP framework among CAKE, Symphony and TRAX? I need to choose just one of those to study and would appreciate your opinion on which is the easiest.
    Thanks
  • NuvoNuvo Forum Leader VPS - Virtual Prince of the Server
    I can't say I have used TRAX, CAKE or Symphony as of yet.
    I picked up Django (python) and Rails (ruby) because both have some advantages over PHP, such as proper OOP support.
    I may try out CAKE and Symphony though as those are the two PHP frameworks I hear of the most.
    PHP, CSS, XHTML, Delphi, Ruby on Rails & more.
    Current project: CMS Object.
    Most recent change: Theme support is up and running... So long as I use my theme resource loaders instead of that in the Rails plug-in.
    Release date: NEVER!!!
  • DeluxeNamesDeluxeNames Admin Administrator
    Nuvo wrote: »
    I can't say I have used TRAX, CAKE or Symphony as of yet.
    I picked up Django (python) and Rails (ruby) because both have some advantages over PHP, such as proper OOP support.
    I may try out CAKE and Symphony though as those are the two PHP frameworks I hear of the most.

    Cool, if you do, let me know what you think of them and which is the easiest.
Sign In or Register to comment.