//DEVGURU

Archives: January, 2009

Rails 2.2.2, Ajax and respond_to

Saturday, January 31st, 2009

As I wrote some time ago in the article about Rails, Ajax and jQuery, sometimes there are problems with Rails not interpreting correctly content type headers of ajax requests. It’s because not all web browsers send that header in the same way.

What I proposed was to sort the request.accepts array (array containing content type headers sent by browser) so that xml content type would be the first element. That would then trigger format.xml in our respond_to block.

However that approach does not work in Rails 2.2.2, because now the request.accepts array is frozen and it cannot be modified. I spent some time googling for the solution, but with no effect. So I dived into the API and Rails’ source code and came up with pretty nice and simple solution to the problem.

class ApplicationController < ActionController::Base
  before_filter :xhr_to_xml

  def xhr_to_xml
    request.format = :xml if request.xhr?
  end
end

This piece of code is an equivalent of the snippet I proposed in the article I referred to at the beginning. Now all ajax request will trigger format.xml in respond_to blocks.

Authentication made easy: Authlogic

Wednesday, January 28th, 2009

Before Authlogic, here at Netguru we we’re using Restful Authentication to handle user authentication.

Because we think that Rails applications should be restful. And so should be the authentication systems. But restful auth had some downsides – it was generating so much code that our user model was too messy (Digitalism should change their lyrics to “so take a look at my User model, it’s such a mess!”). Then I started looking for some better way. Wiktor suggested that I should try authgasm, but! Authgasm has changed it’s name to Authlogic.

Idea
What’s so good about it? It’s just as DRY and clean as authentication plugin can be. All that we need to do is define “acts_as_authentic” in our user model, generate the UserSession model and create a restful UserSessions controller, where we need to create and save an UserSession. Just like any other ActiveRecord model.

Features
Doesn’t sound nice enough? We can customize almost every aspect of it. We want to use email as user’s login? No problem, it’ll check uniqueness and even validate_format_of. We want to scope the uniqueness validation of login to certain account? No problem, just pass the :scope => :account_id to acts_as_authentic and then change UserSessions controller to use @account.user_sessions. We want to log such things as login count, last login ip or current login date? Just create “magic columns” named login_count, last_login_ip, current_login_at. Persistence tokens, single access tokens? It’s all there. It’s also framework agnostic and can easily support OpenID…

What next? I recommend you to check the readme and example rails application with authlogic. It’s worth giving a try.

What stuff I found in Rails 2.2

Monday, January 26th, 2009
When I started our first serious project in Rails the latest stable version was 2.1. Altrough I were still learning the framework, it quickly became obvious that some of it’s internals could have been implemented better. And in fact the next stable version, 2.2, which was released few months ago, was improved in many of the aspects I were thinking of.  Here are the new features I welcomed the most:

  • Added :only and :except to map.resources to let people cut down on the number of redundant routes in an application. Typically only useful for huge routesets.

You can find :only and :except in many places in the rails application and now, finally, in routes too. Usage:

  • Fixed that polymorphic_url should compact given array.

That will definitely dry up some code if you’re using polymorphic routes extensively.

  • Routes may be restricted to lists of HTTP methods instead of a single method or :any.

I could never really understand why I need to specify :any if I only want to allow POST and GET in my actions and not PUT or DELETE. Not more such problems after that fix. Usage:

  • Add :as option to render a collection of partials with a custom local variable name.

That is cool. No more setting :locals or variable renaming inside the parial. Usage:

  • Added block-call style to link_to

Nice alternative to one-line link_to’s. Helps to format HTML in links nicely. Usage:

  • Merge scoped :joins together instead of overwriting them.

This should be there much earlier. Now be careful, this may expose scoping bugs in your code when you’re migrating from earlier versions of Rails.

  • before_save, before_validation and before_destroy callbacks that return false will now ROLLBACK the transaction. Previously this would have been committed before the processing was aborted.

I never realized that integrity of my Rails 2.1 app database could be abused because of before_* callbacks breaking the action chain. Now I do and I am happy that I’m protected.

  • Allow conditions on multiple tables to be specified using hash.

That is something I was intuitively using when learning Rails which was resulting with errors as this feature had not been implemented at that time. Now it is, great.

  • Wrapped Rails.env in StringInquirer so you can do Rails.env.development?

Nice and pretty looking. No more messing with ENV array.

When I was preparing to making the switch to 2.2 I found out that Rails API documentation is missing lot of stuff. Fortunately that stuff can still be found in Rails changelogs and I recommend that you read them!

Adobe Air, Mac OS X and bus error

Sunday, January 18th, 2009

The problem

I couldn’t start any Adobe AIR application on my MacBook. Any. They were working before, but after some time of not having touched any of them – they stopped working. I sent some reports to Apple, but I bet that they don’t give a damn about it.

The solution

…was quite simple, but hard to find. I thought that it would be nice to have some output using adl command (from AIR sdk). Every app outputted following error:

2009-01-18 16:15:01.250 adl[6206:10b] *** +[WebFontCache fontWithFamily:traits:weight:size:]: unrecognized selector sent to class 0xa01b2480
2009-01-18 16:15:01.252 adl[6206:10b] *** NSTimer ignoring exception '*** +[WebFontCache fontWithFamily:traits:weight:size:]: unrecognized selector sent to class 0xa01b2480' that raised during firing of timer with target 0x149d90 and selector '_playerTimerAction:'
Bus error

And crash!

After hours of searching the web I came to this solution, but it wasn’t working for me. They say that you should remove the Safari Block plugin… In my case, I don’t know if it was caused by Safari Block, because Cooliris plugin was the AIR-harmer (and I’m NOT saying about any bio-related gases, you naughties!).

So I started with removing the Safari Block plugin

Library$ cd InputManagers/
InputManagers$ ls
Cooliris		Glims			SafariBlock		Smart Crash Reports
InputManagers$ sudo rm -rf SafariBlock/

But, as I said, it haven’t fixed anything… So I’ve removed the Cooliris plugin:

~$ cd /Library/InputManagers/
InputManagers$ ls
Cooliris		Glims			Smart Crash Reports
InputManagers$ sudo rm -rf Cooliris/

And voilla! They work fine.

Yeah, the cost of having working AIR runtime is watching internet ads.

Rails and IE false image upload headers.

Wednesday, January 14th, 2009

Some time ago, when I was young and unexperienced (ok, it was an hour ago…), I’ve found out that my image upload form is not working on IE. No errors, but no image either.

Here is what i came to  after an hour of debug:

the model has following validation rule:

validates_attachment_content_type :content, :content_type => ['image/jpeg', 'image/png', 'image/gif']

but IE sends false image header (god knows why?) so you need to add:

‘image/pjpeg’, ‘image/x-png’

to get it going again.

Works like a charm.

Managing hosts on OS X with Ghost Gem

Tuesday, January 13th, 2009

Managing local hosts on OS X was pretty easy back before 10.5 with Network Utility, but since Leopard it’s not so nice – we can edit manually /etc/hosts file or play with few not-so-user-friendly terminal commands.

If we want to manage local hosts painlessly, we can use a ghost gem (found via Robby on Rails).
After launching

we can use ghost commands:

Works for me.

Fragment caching with Memcache and Rails 2.1

Saturday, January 10th, 2009

I’ve only recently had a possibility to try the new Rails 2.1 integrated caching. What I first learned was that there hardly is any documentation about it.

So it took me a while to find out that caching HTML fragments with time-based expiration (with Memcache) is as easy as adding:

config.cache_store = :mem_cache_store, { :namespace => 'myapp_production' }

to your config/environments/production.rb to specify Memcache as the caching mechanism. You can also use memory, or filesystem, but let’s be serious here. Memcache is the way to go. What’smore, time-based expiration doesn’t work for the other ones.

Now you can use something like this in your view:

The hardest thing to google for was the :expires_in option. Remember it only works with memcache.

By the way, it’s a good idea to use Memcache also for session storage. To do so, add the following line to config/environments/production.rb.

config.action_controller.session_store = :mem_cache_store

For more information on the basics check out the blog post by TheWebFellas.

Ruby Tuesday

Tuesday, January 6th, 2009

I can proudly announce that the second Ruby Tuesday meeting (informal beer-meeting of an informal group called poznan.rb – Poznań ruby coders) will take place in Głośna Samotność Dragon Pub, Poznań on January 13th. More informations can be found on rubytuesday.pl. Everyone’s invited, we’re open to new people – feel free to come, no matter if you’re earning big money while developing ruby or just coding it for fun. Also it would be nice to spread the word among any ruby developers near Poznań – if you know somebody, let them know.

JShowCase

Tuesday, January 6th, 2009

Ladies and gentlemen, netguru produly presents JShowCase.com – “a blog with state-of-the-art javascript-served UI solutions.” Enjoy.

obrazek-13

Also, from now on, we’ll be writing posts on devguru in pure english (at least we’ll try to).

Firebug dla IE 6!!!

Friday, January 2nd, 2009

Jakis (dość już długi) czas temu, znajomy pokazał mi rozszerzenie do Firefoxa o nazwie Firebug. Wtedy byłem nim zachwycony i ten zachwyt choć z małymi przerwami nie przestał mnie opuszczać aż do dziś. Ciężko sobie wyobrazić w obecnej chwili webdevelopment bez użycia tego narzędzia, co można zresztą zobaczyć chociażby w poprzednim poście.

I choć jest to niesamowicie przydatne narzędzie ma ono jedną poważną wadę – jak sama nazwa wskazuje będzie działać tylko w Firefoxie.  Część przeglądarek udostępnia nam podobne, mniej lub bardziej przydatne narzędzia (np. Web Inspector w Safari czy Chrome) ale pozostaje jeden duży problem – co z Internet Explorerem 6?

W IE6 oczywiście takie narzędzie przydało by się najbardziej, ze względu na niesamowitą ilość błędów interpretacji CSS’a, czy dość specyficzne (innaczej mówiąc złe) podejście do interpretacji JavaScriptu. Z pomocą może nam przyjść IE Developer Toolbar, jest to jednak narzędzie przygotowane przez sam MS co niech świadczy o jego jakości – co za tym idzie nawet do niego nie zalinkuje.

Dlaczego? Bo z odsieczą przybywa nam DebugBar – i to już jest bardzo poważne narzędzie, którego autorzy większość czasu spędzają prawdopodobnie patrząc na samego Firebuga i myśląc w czym by tu jeszcze go naśladować.

I tak DebugBar udostępnia nam wszystkie najważniejsze funkcjonalności jakie oferuje Firebug, w prawdopodobnie maksymalnej jakości jaką sie da wyciągnąc z IE. Dostajemy dostęp do prawdziwej działającej konsoli JS i prawdzej działającej przeglądarki zasobów http(s) i prawdziwego działającego inspektora elementów strony. Wszystko jest w ogóle prawdziwe i działające, a development w IE6 nagle przestaje być taki straszny.

Ahhh… (westchenie kodera CSS któremu development w IE nagle przestał być taki straszny).

Metric_fu i Rails 2.2

Friday, January 2nd, 2009

O Metric_fu można poczytać u Sebastiana Nowaka – najprościej rzecz biorąc jest to zbiór rake tasków z narzędziami, które sprawdzają nam takie rzeczy jak złożoność kodu czy pokrycie kodu testami (przy użyciu rcov).

Z tym drugim problem mają Railsy 2.2 – po krótkiej korespondencji mailowej z Jake Scruggsem (autorem metric_fu) wynika, że:

  • task “coverage” potrzebuje trochę pracy ;),
  • nie wiadomo, czy coverage zostanie w metric_fu – Jake powołuje się na to, że ludzie często przy testach stosują swoje autorskie rozwiązania i ciężko jest napisać coś, co zadowoli wszystkich
Dodatkowo mamy kawałek kodu, który możemy wrzucić do jakiegoś raketaska i powinien nam “zrcovować” nasze testy: