My personal site has been through a number of transitions. It was initially a flat/traditional/simple PHP based site with a custom ORM layer. Then I decided that I spent longer maintaining the site and wanted to blog more so I changed to using Serendipity. After a while of still not writing many posts and not updating Serendipity for a while my site got hacked. I'd always advised my clients of the risks of using open source software - that you have to keep it updated otherwise a security vulnerability found in the software means you are one evil mind and a google search away from being hacked - and then ignored that advice myself.
Therefore I decided as I was learning/using Symfony at my contract at the time that it would be a good experiment to write it in Symfony. I was very pleased with the site, I relatively quickly got up a blog, tagging and quick links system with a Lucene based search system, RSS feeds, Flickr photos and Google Sitemap generation. The site did fairly well when I posted but I still posted infrequently.
After a while, I realised that the best use of the site wasn't in blogging (although I still plan to blog more and want to make a commitment to blogging once per week - we'll see how I do on that goal) but in using it as a test bed for developing new functionality/playing with the framework. After my previous article on Why I think Ruby on Rails is an ideal web development environment,I recently developed two sites in Ruby on Rails (one small not yet launched, another medium - but I'm the last man in an outsourcing chain the end client doesn't know about so can't name it) I decided to rewrite it again in Ruby on Rails so that I'd enjoy working with it again (as you can tell my spare time is limited so I'd like to do it in a language I actively enjoy rather than just one that pays the bills).
It's been an interesting experiment. It's hard to get direct comparisons as some of the initial build time was coming up with the look and feel, conversion to HTML/CSS and refining how features would work. Also it's hard to get comparisons of lines of code as there are certainly things I'd have done differently if I restarted it now in Symfony. But there are some useful lessons I learnt...
I counted the lines of code very simply by finding the files in certain folders and piping them in to 'wc -l'. I did this for both the Symfony version and the Rails version. Rails has a built in command to get a count of the lines of code 'rake stats' but I didn't use that as it excludes blank lines and comments (and that wouldn't be a fair comparison). I hadn't written any automated tests for either site (although it's next on my todo list for the Rails version) so that wasn't an issue, I didn't include any externally plugins in either count nor the generated Base classes for the Symfony site.
The final figures are: Symfony 2607 lines and Rails 1067 lines. As I said in the introduction this isn't as direct a comparison as I'd like as there are things I'd do different in Symfony, but I do think it's quite indicative that Rails is a lot more concise to get great functionality using features such as Dynamic Finders and Named Scopes.
The original site took about 4 weeks to build (about 2 evenings per week, 1 evening at the weekend of 3-4 hours each) and the rebuild took 3 evenings. However, this isn't as indicative of how quickly a rebuild in Symfony could be done - as I said a lot of the initial build was in putting together this (admittedly ropey) design and considering how features should work.
The next question for me was "OK, so Rails felt faster to build the site, smaller codebase for the same functionality, but Rails can't scale so how fast is it?". Now, I know there's a difference between scaling and speed so please don't bother pointing this out. At the end of the day my personal site will always likely be on my single machine so I'm just interested in how many pages per second the server can process.
A quick Apache benchmark gave me figures of 1.43 requests/second for the Symfony version and 1.08 for the Rails version. To be honest, I didn't build the site for speed so I wasn't bothered about the performance drop - the performance is acceptable. Then I had a thought, the old Symfony component for latest pictures from Flickr was cached for a few hours but I hadn't done any caching for the Rails version. A quick retest showed a much more respectable 13.41 requests/second - nearly 10x faster than the Symfony version!! We've had some performance problems with Symfony at my current contract, but I wasn't aware it was that much slower than competing frameworks.
As a side note: I've very recently added comments to the site, haven't optimised it at all and it's now dropped down to 7.31 requests/second but I'm aiming to add some optimisations in there and see if I can easily get it above 10 req/s again.
Symfony applications have an enforced structure necessitated really through working in an MVC style. However, beyond that there isn't much information out there on coding style and how to do things "the Symfony way" to the same extent as there is on Rails. Rails is well known to be opinionated software - the framework works better if you follow certain conventions (e.g. plural table names, singular model names, RESTful controllers, etc) and because of this it has a much bigger community eschewing their opinion on the right way of writing code in Rails.
This is a good thing and a bad thing - personally I see nothing wrong with the code "for object in collection" as opposed to "collection.each do |object|" but at least they have an opinion. For some easy learning of some of the Rails community's opinions on MVC and code structuring such as Jamis Buck's important article Fat Model, Skinny Controller watch the videos by the Rails Envy guys called MVC Public Service Announcements. There are also resources such as PeepCode.com's Rails Code Review document which gives a lot of style pointers.
Reading a lot of information about how Rails code "should" look helped a lot in the learning process and I feel like I've a)come out with a better finished site and b)learnt a lot that benefits me in my day job as a Symfony developer.
The obvious question from one of my points above during the lines of code comparison must be "why the hell haven't you got automated tests for your Rails version? That's near criminally negligent!". Well, the short answer is that I wanted to get the Rails conversion done as quickly as possible. I wanted to add comments to the site as I never bothered in the first build and didn't want to waste the time adding them to the Symfony version when I knew I was rewriting it.
So, now I've got the new site up, with comments and now social network sharing - my number one job is to go back and write automated tests. I've been considering using RSpec or Shoulda, but at the end of the day I've used normal Test::Unit for my previous two Rails projects and it served me well.
One thing I would like to recommend is Autotest from the ZenTest gem. This basically is a daemon that runs in the background and automatically reruns your tests as related files change (e.g. change a model or a fixture file and your unit tests for that model will rerun) and then pops up a Growl notification (on Macs) that lets you know if they passed or fail. It's like continuous testing on a local machine as you make each change.
The old Symfony based site was pushed up using Unison over SSH. This worked relatively well and I didn't really have anything better. Now I'm using the best deployment software on the planet - Capistrano. I have it set to deploy from git on my server, run any database migrations and restart ferret on each deployment. I'm hosting using Apache2 with Phusion Passenger.
That was always my concern when I first started looking in to Rails - the whole proxy to mongrels configuration mess. Now, with Passenger it really is easy and a quick touch of a file (which Capistrano does for me) quickly tells it to reread all the files on a new release.
Well, as you can probably guess I'm very happy with the new site code. I added comments over (realistically) two evenings, including Ajax uploading of the comment, a sprinkling of jQuery to make this show/hide/change and Akismet to give them a first pass at checking for spam. On the whole, I've found it a very enjoyable experience. One of the best parts has been converting my code from PHP to Rails line-by-line and then working out what the more Rails-way of doing things is and refactoring it.
When adding functionality I'm finding it much easier to reread the code as Ruby has a much more readable syntax where you tend to chain methods together rather than nest them (in fact this is very jQuery-like - I've got a future post coming up about jQuery and why I like it so much).
Overall I'd rate it a great success. What are your thoughts on PHP, Symfony and Rails? Have you converted a site from PHP to Rails (or vice versa even)?
Let me know in the comments.
17 Comments so far
Paul Ardeleanu wrote on 07 November 2008 at 13:06
I'm glad you reached this conclusion and good luck with the tests.
Try TDD on the next project ;)
Paul Ardeleanu wrote on 07 November 2008 at 13:08
Man, you have an error when listing the articles in a month:
http://andyjeffries.co.uk/articles/on/2008/6
ExceptionNotifier will save your life:
http://agilewebdevelopment.com/plugins/exception_notifier
;)
Andy Jeffries wrote on 07 November 2008 at 13:18
Thanks mate. I'm aware of the missing year/month functionality, it's on my todo list.
I'm actually using Hoptoad which is much better than exception_notifier - http://www.hoptoadapp.com/welcome
Andy Jeffries wrote on 07 November 2008 at 13:18
Also, I'm using TDD on a couple of side projects, it's worked very well. But I find it more useful for building a top quality project rather than a fast project. For my personal blog, getting it up quick was more important than getting it perfect ;-)
yuri wrote on 07 November 2008 at 13:19
Just don't make excuses for not having written any tests OK?
Tests have their own goals, they are not written for the sake of tests, like many tdd proponents want you to do.
Your site is already written, it's not very large, there's one person working on it, so it's just fine!
So tired of these TDD cowboys.
Andy Jeffries wrote on 07 November 2008 at 13:23
@yuri: The tests are coming. I see their benefit quite clearly in my day job (we work in a Scrum/Agile environment so automated tests are an essential part of it) and absolutely think they're necessary.
They'll be done in the next few days... Thanks for the comment though (you're my first comment from someone I don't know so I'm really pleased)
Rob wrote on 07 November 2008 at 14:49
Nice post, thanks Andy. It's very interesting to see how a PHP developer takes to Rails. I personally prefer Python as a language and for the breadth of the plugin catalogue but have been almost tempted by Rails because there doesn't seem to be anything quite as nice in Python. Here's hoping TurboGears turns out as well as it looks.
I'm not convinced that lines of code is a great way of comparing two frameworks as quite a lot of that is going to be down to the syntax of the language.
Derek wrote on 07 November 2008 at 17:41
If you're learning Rails coming from PHP, the Rails for PHP reference (http://railsforphp.com/reference/) is a good resource for finding the equivalent Ruby code for common PHP functions.
merbist wrote on 10 November 2008 at 03:05
merb is fastest:
http://www.slideshare.net/wycats/merb-camp-keynote-presentation?type=powerpoint
Andy Jeffries wrote on 10 November 2008 at 08:42
@Derek - that site is a great resource. I often use it as it's similar to the PHP site, e.g. you can type: http://railsforphp.com/urlencode and it will give you the information on the equivalent functionality for Rails (although it doesn't mention the u() helper on there).
Andy Jeffries wrote on 10 November 2008 at 08:46
@merbist - I am following Merb, although I'm too new to Rails really (only been using it since the start of this year in anger) to consider switching.
I did see this interesting URL earlier though: http://www.rubyinside.com/44-merb-resources-1318.html
Ahad Bokhari wrote on 30 November 2008 at 11:04
I agree with Andy on this one...
Ahad Bokhari wrote on 30 November 2008 at 11:18
@Andy excuse the back to back comments. your xhtml <\blockquote> syntax seems a little odd - shouldn't it be on the text legend underneath?
You've been spending alot of time on command line prompts huh? hehehe ;-)
Feel free to delete this comment..
Andy Jeffries wrote on 30 November 2008 at 20:52
@Ahad: thanks for the comment, I won't delete it (I really don't want to be getting in the habit of deleting comments unless they are really offensive). I did however delete the duplicate comment that came through without guilt.
Thanks for all your comments though, on this and the other post. Greatly appreciate.
Ruby on Rails Outsourcing wrote on 21 May 2009 at 06:08
Thanks mate. I'm aware of the missing year/month functionality
Andy Jeffries wrote on 21 May 2009 at 08:16
I'm actually about to redesign the look of my site and that sidebar element isn't there in the new version. Thanks for the nudge though :-)
MiraƧ wrote on 25 March 2011 at 12:35
Nice topic. I love Ruby on Rails. Because happy developers :)
plug-ins works for me too.
ruby-gems is cool!
so I'm happy =)
I don't know about of symfony, the performance was bad you said. I'm make a example on symfony with php.
Click here to have your say...