//DEVGURU

Author's entries:

Work environments of Rails developers #1: Ryan Daigle

Wednesday, April 8th, 2009

Taken from Ryan’s blog:

Ryan Daigle is an independant developer working as Y|Factorial, LLC, a ruby and iPhone software consultancy.

He also writes Ryan’s Scraps, the “What’s new in edge rails” blog.

Bartosz Pietrzak: Which OS and which editor are you using?
Ryan Daigle: I’m on Mac OS X which means that I use Textmate  for most of my work.

Do you prefer GIT or SVN?
I prefer GIT, although I’m not a GIT master, but I do prefer it.

Do you see any upsides or downsides of using GIT, comparing it to SVN?
Well, certainly there are a lot of benefits, like easy branching, low cost branching and things of that nature. As far as downsides, I think it’s more complex tool, so it takes a little more effort to become very efficient at it, but that’s hardly a downside. It just means that it might require a little more effort to become good at using that tool.

What plugins or gems do you usually generate your new apps with?
Let’s see… I use HAML, make resourceful, rspec, cucumber, all those gems. Let me open up one of my projects right now. Will_paginate, HAML and  make resourceful – these are the core ones that I tend to at least start with.

What’s your strategy for populating your database with some predefined data? Do you use migrations, fixtures, rake tasks with gems like populator?
For staging data, for data that I just want to populate the database to play with the app I usually have a rake task that use something like factory girl or, there’s a plugin I highly recommend, called dataset, which is a fixture replacement, but it lets you load predefined set of data with one rake task. So I use that for staging data and if it’s setup data, configuration data for the application that needs to be present in production and staging, then I usually write a custom rake task, but the point being I keep it out of my migrations, because I don’t think that migrations are the place to do data population. Migrations are place to alter the structure of your database and occasionally, in the course of altering the structure of the database you do need to tweak or change something, but as for data population I keep it out of my migrations.

What is your opinion on TDD?
My opinion is that it’s great and it’s certainly what I choose to use to start things off. There are many different tools that you can use in TDD but as far as general methodology is concerned I certainly am keen on it.

You’ve mentioned Rspec. What do you think about Shoulda?
I’ve obviously heard about Shoulda, Mocha and they seem to have good reputation, I’d just not had the least recognition needed to anything other than rspec, so I’m still using rspec and haven’t really looked into the others. Although recently I started doing Cucumber, Webrat and rSpec, it’s kinda my testing stack and I’ve enjoyed that process.

How do you think Rails development process will change after 3.0 release?
Oh, that’s a tough one! I mean, I’ve not seen much actual work come through on the Rails source on github so it’s hard to say if most of the changes will have limited  external effects and mostly just internal tweaks and refactorings, although I think one of the stated goals will be to make rails a little more componentized, a little more accessible without of monkey patching rails classes to overwrite functionality and add new functionality, I think they gonna try to give you more predefined points at which you can hook into their functionality, so I think for plugin writers and gem writes and engine writers I think the development process will be a lot cleaner and a lot more stable, as far as everyday developers I’m not quite sure yet how they’ll be impacted.

What usually do you do with your team first, design of the applications or the you know, code and the functionality of the applications?
When you say design, do you mean visual design?

Yes.
Ok, so usually when I start on a project I like to have at least wireframes in place so I like for my client to have at least thought about the functionality that their users will see, but I don’t necessarily want the visual design in place, I don’t need to see fonts, sizes and colors and pretty graphics, I just need to know how the client’s envisioning their functionality will be exposed to the user. And then when I start on, my preference is to have visual design kinda be done in parallel, or at least maybe week or two in front of development, I feel like if you treat visual design and development as two separate deliverables, then often in the end, when you try to bring those two sides together there’s a lot of work that goes into melding the two, so if you can treat it as one highly integrated process throughout your outcome will be much better. So, in the beginning I do like to see a visual representation of the functionality that needs to be developed, but I don’t need to see a visual design.

Do you prefer the getting real way of creating the applications or huge specifications?
Well, certainly I’m against huge specs of any kind, so I would have to come down on the side of getting real, I feel like not everybody has a luxury of such a freeform process as getting real, but certainly the main tense of that thought process I do support.

These will be private ones, do you prefer working from home or from office?
I think there are definitely benefits to an office, but I think if you are working with a group of people that you’re familiar with, and you know their work style, and you trust the work they do I think working from home can be more productive since you’re outside of the realm of those frequent interruptions that happen in office and really let you be quite productive, so I think for my productivity sake I enjoy working from home and occasionally it makes sense to get together to discuss something in person, but for the majority of the time I think working from home is beneficial.

Do you prefer night time or day time and what about separating work from private life?
I’m not a morning person but I start my day pretty early, because I like to have my work done somewhat early, so that I can have the late afternoon and evenings for myself, for personal time, so come 4:30 or 5 o’clock I usually, you know, I don’t turn off my computer but I put it away wherever I go, go running, go to the gym or do something like that and force myself to get out of the house and that’s serves as my formal break between work time and personal time. And then the weekend it’s the same thing, I don’t really feel compelled to go to my home office and start working on the weekends, it’s just structured that way, so I don’t really think about that. It doesn’t mean everything’s done during the week. Maybe I’ll just fire off some emails, but I don’t really get into core work mode during personal time.

Useful gems: Quick Scopes

Thursday, March 26th, 2009

Some time ago I’ve found an useful gem – internuity’s quick scopes.

As readme for the plugin says,

A Rails plugin to automatically add some quick named_scopes to your models.

These are especially useful for quick modifications to a query on an association.

It creates default named_scopes for any of your models:

  • order
  • limit
  • offset
  • with – alias for :include
  • where – alias for :conditions

Personally I don’t like mixing named_scopes with :conditions and :order options – with this gem we can chain our scopes with limit, order etc:

  user.posts.order('created_at')

  user.posts.where(:published => true)

Another small thing that makes our code cleaner.

Colors in GIT

Saturday, February 21st, 2009

This one will be short:

git config --global color.ui true

The command above will color your git output (branches, file status etc) green and red. Very, very handy.

The Ultimate Website Launch Checklist

Thursday, February 19th, 2009

websitelaunchGuys form Box UK released “a checklist that all websites should be checked against before launch“. It’s full of “oh, I know that!”, but I can imagine finding it very helpful when estimating project due dates and, of course, when launching the website/app – because you probably won’t remember some of them. Pretty cool.

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.

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.

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.

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).

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:

Netguru @ CR & IT Conference, Częstochowa

Monday, December 15th, 2008

W miniony weekend poprowadziliśmy 4 prezentacje na konferencji CR & IT w Częstochowie:

Materiały są podlinkowane.

Przyspieszanie nowych Railsów: memoization

Tuesday, December 9th, 2008

Problem?

Termin memoization nie jest niczym nowym w programowaniu, prawie-rzetelne źródła podają rok 1968 jako pierwsze pojawienie się go.

Na czym polega memoizacja (że tak sobie pozwolę na spolszczenie)? Proste: metoda zapamiętuje (można o tym pomyśleć jak o keszowaniu) swój wynik (w zależności od podanych argumentów) i wywołana kolejny raz – zwraca zapamiętaną i zamrożoną wartość.

Implementacja w Railsach

Memoization było często stosowaną praktyką – pisane “z ręki”, ale jako metoda ActiveSupport weszło do core railsów kilka m-cy temu, dzięki czemu wyszło wraz z wersją 2.2. Spróbujmy!

W ten sposób metoda wywołana kolejny raz nie będzie wykonywać skomplikowanych obliczeń, a jedynie zwróci swoją zmemoizowaną wartość. Co więcej, metoda może przyjmować argumenty – i zapamiętuje swoją wartość w zależności od podanego argumentu!

Tak więc mamy bardzo miły sposób na nie-zarzynanie rubiego.

Kiedy nie stosować memoizacji?

W przypadku dynamiczności zwracanych wyników (kiedy metoda korzysta np. z Time.now). Wyniki są zamrożone dla danego requestu i jeśli chcemy, żeby podczas niego obliczała coś kilka razy – odpuścmy sobie memoizację (lub wykonajmy zmemoizowaną metodę z symbolem :reload jako ostatnim argumentem).

Javascript, jQuery i preloading obrazków

Wednesday, November 26th, 2008

Wiemy już w czym problem, prawda? Chodzi o te pół, jedną trzecią, dwie szóste czy nawet całą, a nie daj Boże dwie i więcej sekundy, po których pojawia się obrazke zdefiniowany w css na zdarzeniu hover. Rozwiązań jest kilka, z czego na chwilę obecną przychodzi mi do głowy np. CSS Sprites, czyli działające-aczkolwiek-średnio-wygodne rozwiązanie.

Jakie rozwiązanie jest zadowalające-prawie-wszystkich a zarazem banalne w użyciu? Preloading przy użyciu jQuery.

Ot, cała filozofia: w DOMie tworzony jest obiekt img, który dostaje odpowiedni atrybut src, co powoduje wczytanie tego pliku do cache przeglądarki. Problem “opóźnionych hoverów” z głowy.

Railsowa magia nie do końca skuteczna, czyli counter cache

Wednesday, November 19th, 2008

Magia!

Railsy są tworzone z myślą “konwencja nad konfiguracją” – czego jednym z przykładów może być counter cache. Jak to działa?

Mamy model User. User ma wiele Postów, więc Post belongs_to :user. Chcemy wyświetlić liczbę postów, jakie napisał użytkownik. Wywołując, dajmy na to, User.first.posts.count dostajemy aktualną liczbę rekordów Post w bazie. Nic zaskakującego. Jeśli zdefiniujemy w tabeli users pole “posts_count” a przy definiowaniu relacji Post belongs_to :user dodamy :counter_cache => true – liczba postów należących do użytkownika będzie zapisywana w rekordzie użytkownika (a konkretnie – inkrementowna lub dekrementowana przy tworzeniu postów), przez co (kosztem nadmiarowości (redundancja to zbyt egzotyczne, jak dla mnie, słowo) – ale to mocno dyskusyjna sprawa) oszczędzamy sobie zapytań SQL zmuszających bazę do nieustannego mielenia. Fajne.

Fajne – w standardowych przypadkach.

“Konwencja nad konfiguracją” ma to do siebie, że działa w standardowych zastosowaniach, a problemy pojawiają się, gdy chcemy rozszerzyć jakąś funkcjonalność.

Przykład: komentarze muszą zostać zatwierdzone przez moderatora, a więc nie chcemy podliczać użytkownikowi zawieszonych przez moderatora komentarzy (a jedynie te aktywne – do takich rzeczy polecam acts_as_state_machine). Counter_cache w tym przypadku odpada – będzie inkrementował licznik komnetarzy przy stworzeniu, dekrementował przy wywołaniu destroy, ale zmiana stanu na nic nie wpłynie.

Napiszmy to sami.

Odpuścimy sobie ustawianie counter_cache na true przy belongs_to i dopiszemy kilka callbacków w modelu komentarza:

(Powyższy kod zakłada, że mamy zdefiniowane named_scope :active).
Zastosowań tej metody jest więcej – możemy np. nie usuwać rekordów z bazy przy usuwaniu komentarza, a jedynie zmieniać jego stan (acts_as_state_machine!) na “deleted” i wyświetlać ładną informację pt. “ten komentarz został usunięty”, przez co nie zaburzamy toku dyskusji – after_save wywoływany przy zmianie stanu zmieni liczbę komentarzy na aktualną; działa też b. fajnie w momencie gdy obiekt nie zostaje stworzony, a jedynie przypisany parentowi (po drobnej modyfikacji, rzecz jasna).

Javascript a ładny kod: Object Literal

Tuesday, November 18th, 2008

Problem

Jak wygląda praca z Javascriptem z punktu widzenia server-side’owego developera?

Przeszliśmy pierwszą falę szału nad bibliotekami JS: Prototype, Mootools, jQuery (czy mniej buzzowe ext.js, YUI). Zachwycamy się ładnymi rzeczami tworzonymi przy użyciu canvas, które znajdujemy na oursignal.com (też przecież napisanym w JS). Widzimy, jak za pomocą jednej linii możemy schować, animować, przetransformować i zrobić milion rzeczy z DIVem, Paragrafem czy Anchorem. Wybieramy jedną z bibliotek. Czytamy dokumentację, widzimy milion fajnych selektorów, czytamy książki, w których zachwycamy się jak fajnie można rozszerzyć funkcjonalność o pluginy… Myślimy sobie: “tak, teraz, gdy JS nie jest tak paskudny i skopmlikowany jak kiedyś, mogę stać się JS-developerem!”. Piszemy więc accordion, animujemy kilka rzeczy w naszej aplikacji (żeby user widział, że się dzieje!), kilka formularzy wysyłamy AJAXem. Wszystko jest ładne i unobtrusive. I co?

Zdajemy sobie nagle sprawę, że nasz application.js ma o kilkaset linii kodu za dużo, że kod jest nieczytelny, że nie wszystko da się wrzucić do document.ready(), że kilku rzeczy moglibyśmy użyć w kilku miejscach – zaczynamy pisać więc funkcje, staramy się przyjąć jakąś konwencję nazewnictwa… I kończymy z jeszcze większym bałaganem – chociaż bałaganem rozszerzonym o DRY.

Rozwiązanie?

Dobrym punktem wyjścia jest trzymanie wszelkich akcji w jednym obiekcie – korzystając z object literal (kawałek kodu korzysta z jQuery):

Co nam teraz pozostaje? Wywołanie funkcji bob.init(); w document.ready. Korzyści? Mając jeden obiekt “bob” możemy wywoływać jego funkcje w środku odwołując się do self. Trzymając wszelkie informacje, które mogą ulec zmianie – takie, jak długość timeoutu, klasy css czy wiadomości komunikatów – w bob.config – możemy łatwo je zmienić (gdy np. mamy konflikt z koderem CSS). Zresztą kod jest całkiem “samowyjaśniający się“.

Potencjalne zastosowanie? Dajmy na to, że wszystkim input type=submit podpinamy event, który powoduje, że po kliknięciu na niego zmienia value na “ładuję…” i staje się disabled. Ok, pięknie działa dla wszystkich przycisków wygenerowanych przez aplikację. Co jednak, gdy stworzymy nowy input przez javascript? Mamy doczepić mu event w momencie tworzenia? Nie, po umieszczeniu go w DOMie wywołujemy tę samą funkcję, która jest wywoływana przy init(). Warto rozpisywać nawet najmniejsze rzeczy w osobnych funkcjach – nigdy nie wiadomo, czy nie będziemy musieli ich kiedyś użyć ponownie.

Co dalej? Walidujemy nasz JS przy użyciu JSLint, przez co oszczędzimy sobie żmudnego procesu debugowania (który nie jest, swoją drogą, zbyt przyjazny). Kilka ciekawych praktyk zawarł w swojej prezentacji Chris Heilmann (część 1, część 2, wygrzebane przez Filipa Teppera) – m.in. jak umożliwić designerowi/koderowi CSS pracę nad wyglądem strony z Javascriptem lub bez niego – korzystając jedynie z CSS.