sobota, 21 stycznia 2012

Model logic

We all know that our models should be fat and controllers / views are supposed to be simple (dumb). Recently I was asked why such code should be put into model :

What's wrong with using Ad.unverified_ads.last in the view. I don't have an answer for the "why?" question often asked by beginner programmers. You can trust your more advanced colleagues that it should, that it is beneficial and will make your life easier or stick with your current way, wait until the application gets bigger, and regret it later. Anyway, I always ask myself one question when I have to decide whether something probably is part of the model. Would I need this method if the application had different way of interacting with the user. If it was a console application or just an API serving JSON to some clients. Given the previous code example. Can I image an usecase that requires me to display last unverified ad to user interacting with the program via command line. Yep, I can. Is it possible that I am gonna need it when serving JSON response? Might be. So I think I would make it part of the model.

How about this one:

Would I use it in CLI ? Nope. When rendering JSON ? Not really ? So... Not a model.

Third example:

I think it can be part of your model but does not have to. Even if this method could be useful in console application or for JSON api it looks like it still fits better in the presenter layer (or helper) instead of model layer.

I know that the examples are extremely simplified but that's not the point. When you are in doubt, just image that you would also have to implement the same app in completely different environment that has nothing to do with HTML. Which parts would you still keep in your model ? Asking myself such questions helps me make right decisions.

sobota, 14 stycznia 2012

Active Reload - mission accomplished

Once upon a time I was working on a big Rails application and every time I wanted to fix some CSS or JS issues I had to wait for a few seconds to reload the page which was making me really unproductive and unmotivated. I knew I was not the only one who suffered from such delays when working with big Rails apps. I occasionally spotted some comment about it here and there, in blog comments, reddit, rails forums. There were also other solutions that tried to fix the problem rails-dev-boost, rails_dev_mode_performance but had their limitations. So I decided to do something about. My initial trials were overcomplicated, error prone but eventually I created something that was working fine for my project. And it made my productive on that project again and much more happier. The solution was so incredibly simple (in concept and in materialization) that I still find it astonishing that no one before released such thing as a gem.

The fact that it was working for me meant nothing and proved nothing also. The gem needed to be tested by wider audience which would probably be very skeptical about it. So I had to have their attention somehow. I wanted to show to other people how I felt when using this gem, what is the profit of using it but I could not show the application that I was working on at that time. Also that would not convince anyone since well YMMV and nobody would be able to repeat my performance research without access to my application. My friends from DRUG (Dolnośląski Ruby User Group - the organizers of wroc_love.rb conference) advised me to check out if it works with spree . It turned out to work pretty well so I recorded two videos showing the difference. I used bbq which uses capybara under the hood to driver the browser automatically and make the test independent of human activity which could disturb it. I also provided exact steps to repeat so that everyone could challenge me.

Michał Łomnicki invented this catching phrase "Rails development mode 300% faster" and used it to submit a post to reddit. I did not want initially to make this solution part of Rails code because I knew that at that moment it would be probably hard for me to convince Rails core team that it is useful, working  and could actually solve some people problems. My plan was to make a gem, hope for some buzz, fix bugs, hope that Rails core won't ignore it and will merge it into Rails itself. It all stared to work...

I must admit I wasn't the best gem maintainer. I could not fix some bugs, merging some pull requests took me too much time, testing the gem with newest Rails releases happened often weeks later. Guilty as charged. But it does not change the fact the gem seemed to be helping other people and most of the time did its job well. I wish I could somehow count the amount of time that it saved.

Than one day I woke up and saw that Jose Valim merged Active Reload into Rails and also fixed some bugs during that process and even added very simple solutions to problems that I could not solve (ex.: how to quickly detect changes on database caused by migrations when model file did not change - his solution: observe also schema.rb file which is regenerated after running migrations). And it was like: OMG my gem is in Rails :). And it happened exactly as I planned.

It convinced me that:
  • after so many years you can still have impact over general Rails shape,
  • even when you only spend couple of hours trying to make it better;
  • it does not matter if people know you or not, you can still make a difference and become somehow known in this process;
  • sometimes you only need dozes of lines of code instead of hundreds to make a difference;
  • If it is important to the community, Rails core will notice it and incorporate;
  • If you have some idea: make gem, advertise it (movie is must have in Rails world, sorry) and watch what will happen, maybe something bigger than you imagined. Maybe nothing but it will be still worth trying.
Since Active Reload is now part of Rails ( Announcement ) and it did its job I will no longer maintain it. If it works for your Rails 3.0 or 3.1 application, good. If it does not, try upgrading to 3.2 and maybe you will have a better luck. If there is any problem with this solution in Rails 3.2, create an issue on github. It is now in the hands of Rails community. We are now all responsible to remember that Rails was supposed to allow us developing applications quickly. That's why we felt in love with it. We wanted to make blogs in 15 minutes, not hours.

Die Active Reload, long live Rails.