ActiveRecord met Ambition
Geplaatst door Remco van 't Veer do, 30 aug 2007 08:55:00 GMT
ActiveRecord krijgt veel lof en wordt naast ActiveSupport ook veel buiten Rails gebruikt. Migraties zijn prachtig vooral de sexy variant, associaties zijn duidelijk op te schrijven en er is een mooie manier om validaties op te schrijven. Maar kan het allemaal niet veel mooier?
Chris Wanstrath is begonnen aan een ambitieus project om de ActiveRecord DSL naar het volgende niveau te trekken; Ambition. Z’n aanpak introduceert de methodes van het Enumerable op je ActiveRecord model classes;
@users = User.select { |m| m.name != 'macgyver' }
is grof weg equivalent aan:
@users = User.find(:all, :conditions => ["name <> 'macgyver'])
Naast dat de variant van Chris veel meer op Ruby lijkt en, naar mijn mening, veel mooier is, is er nog een subtiel verschil. De ambition variant levert geen array zoals find
doet, maar een Query
object welke zich gedraagt als een array. Pas als er elementen uit de array gehaald worden, met each
, first
etcerata, wordt de query door ActiveRecord uitgevoerd.
Ik zit nog steeds met m’n mond open van iets tussen verbazing en genot. Kan bijna niet wachten op Rails 3.0 of zullen we 2.0 maar gewoon uitstellen? ;)
Toevallig (of juist niet) heb ik hier vanmorgen ook even naar gekeken.
Ik ben absoluut van plan Ambition binnenkort eens te implementeren in een test-project!
Mooi! Maar hoe maak je een combinate van criteria?
Persoonlijk vind ik de builder structuur zoals deze in GORM (Groovys’ ORM laag) bestaat erg goed… maar ik ga er van uit dat dit ook in Ambition mooi wordt opgelost?
Schitterend! En weer een restje ouderwetsheid de deur uit.
Maar ik zie nog niet het voordeel van het uitstellen van de query tot je hem daadwerkelijk gebruikt. Als je hem geschreven hebt ga ik er van uit dat je hem ook nodig hebt. Of mis ik nu iets heel overduidelijks?
Één van de mogelijke voordelen van een dergelijk query object is dat je het resultaat ‘lazy’ kunt gaan ophalen; als je alleen first aanroept hoef je niet de hele lijst op te halen en om te zetten in objecten….
In het gerefereerde artikel staat ook als voorbeeld dat het aanroepen van ‘size’ op het query object bijvoorbeeld een count in de database uitvoert ipv. een fetch waarna de lengte van de array bekeken wordt.
Overigens vind ik het feit dat het query object een ‘to_sql’ methode heeft ook echt niet verkeerd hoor!
Zie ook het caching voorbeeld in het artikel, onder het kopje “Kicking Around Data” om een beeld te krijgen waarom het stellen van de query voordelen kan hebben.