Ahh, noen ganger blir jeg litt ekstra fornøyd når jeg ser hvordan enkle grep i Ruby gjør småting som i utgangspunktet skurrer mye bedre. Ikke at det er spesielt avanserte ting, men dette gjør at jeg sover litt bedre om natten:
I Flere i bilen har jeg et par modeller Route og RouteSearch. Reisen (Route) har attributtene mandag, tirsdag, onsdag, torsdag, fredag, lørdag, og søndag. På reiser kan det krysses av for hvilke dager de kjøres og følgelig blir korrespondere dager satt til true. I Reise-modellen gjøres også disse dagene tilgjengelige for masse-tilordning via attr_accessible, og jeg har lagt på mulighet for å hente ut for eksempel alle reiser som går på mandager med Route.mondays via named_scope. En liten hjelpefunksjon svarer på om noen dager er valgt i det hele tatt. Denne funksjonaliteten er definert ca som følger:
class Route < ActiveRecord::Base
DAY_ATTRIBUTES = [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday]
attr_accessible *DAY_ATTRIBUTES
DAY_ATTRIBUTES.each do |day|
# Oppretter mondays, tuesdays etc, SQL condition monday = true
named_scope day.to_s.pluralize, :conditions => {day => true}
end
def any_days_selected?
DAY_ATTRIBUTES.each {|day| return true if send("#{day}?")}
false
end
# mer kode her..
end
Som nevnt har jeg et par modeller, og modellen som står for Reisesøk har også ukedager som attributter. Når mandag blir satt til true på et reisesøk vil route_search.routes kun returnere reiser som kjøres på mandager osv. Et reisesøk skal også ha dagene tilgjengelig via masse-tilordning, den skal kunne svare på om en eller flere dager er valgt i det hele tatt og det kan godt ha funksjonalitet så jeg kan hente ut alle Reisesøk som søker etter reiser på mandager. Med andre ord er funksjonaliteten til de to modellene når det gjelder ukedager like. Det enkleste løsningen, men samtidig den som bør få folk til å sove dårligst om natten, er litt klipp og lim. En annen mulighet kunne vært via arv, men en reise og et reisesøk er strengt tatt ikke en type av den andre.
Ruby støtter moduler der funksjonalitet kan grupperes og etter en liten ommøblering (noen som har et godt ord for refactor?) i koden ser Route-klassen nå slik ut:
class Route < ActiveRecord::Base include CommonBehaviourForWeekdays end class RouteSearch < ActiveRecord::Base include CommonBehaviourForWeekdays end
Mye bedre enn klipp og lim! ..og hva har vi i CommonBehaviourForWeekdays?
module CommonBehaviourForWeekdays
DAY_ATTRIBUTES = [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday]
module HelperMethods
class << self
def attach_named_scope_for_day_names_on(base)
DAY_ATTRIBUTES.each do |day|
base.named_scope day.to_s.pluralize, :conditions => {day => true}
end
end
def make_days_attr_accessible_on(base)
base.attr_accessible *DAY_ATTRIBUTES
end
end
end
# Hook som blir kjørt når denne modulen blir inkludert
def self.included(base)
HelperMethods.attach_named_scope_for_day_names_on base
HelperMethods.make_days_attr_accessible_on base
end
def any_days_selected?
DAY_ATTRIBUTES.each {|day| return true if send("#{day}?")}
false
end
end
Vi har nå delt samme funksjonalitet over flere klasser, men samtidig holdt implementasjonen av denne funksjonaliteten på ett sted.

Legg igjen en kommentar
Kommentar-feed for denne artikkelen