Collection finders
Hračky jako has_one, has_many, belongs_to, habtm a has_many :through všichni snad znají a hojně používají. Rozdíl je ale v hloubce pochopení a využití těchto asociací.
Dnes jsem došel k zajímavému poznání. Týká se především násobných asociací jako je například has_many. Dejme tomu, že mám model firma -> zaměstnanci (1:N) a potřebuji najít všechny zaměstnance v systému s platem vyšším než 10 korun.
Employee.find(:all, :conditions => ["salary > ?", 10])
Jednoduché jako facka, tady není co řešit. Nicméně tento příklad moc realitu nepostihuje. Chceme vidět jenom zaměstnance naší firmy:
Employee.find(
:all,
:conditions =>
[ "company_id = ? AND salary > ?",
my_company.id, 10]
)
Tady je z pohledu syntaktického taktéž vše v pořádku. Kód funguje a dělá přesně to, co po něm chceme. Problém je v tom, že svatý princip Rails nazvaný vtipně DRY (neopakujmež se!) dostává ránu pálkou do rozkroku. Au! To opakování fakt bolí. Na filtrování zaměstnanců naší firmy přece máme metodu employees ve třídě company:
class Company
has_many :employees
end
Ta nám ale vrací pole zaměstnanců. Chyba lávky! Company#employees vrací cosi, co se chová jako pole (nebo taky seznam), ale je to objekt mnohem chytřejší. Dobře placené zaměstnance naší firmy najdeme třeba takto:
my_company.employees.find(:all,
:conditions => ["salary > ?", 10])
Super ne? Neopakujmež se tedy.