Powiedzmy, że mam następujące klasy
class SolarSystem < ActiveRecord::Base
has_many :planets
end
class Planet < ActiveRecord::Base
scope :life_supporting, where('distance_from_sun > ?', 5).order('diameter ASC')
end
Planet
ma zakres life_supporting
i SolarSystem
has_many :planets
. Chciałbym zdefiniować moją relację has_many, aby gdy pytam solar_system
o wszystkie powiązane planets
, life_supporting
zakres jest stosowany automatycznie. Zasadniczo chciałbym solar_system.planets == solar_system.planets.life_supporting
.
Wymagania
Ja nie chce zmienić
scope :life_supporting
wPlanet
celudefault_scope where('distance_from_sun > ?', 5).order('diameter ASC')
Chciałbym również zapobiec powielaniu, ponieważ nie muszę nic dodawać
SolarSystem
has_many :planets, :conditions => ['distance_from_sun > ?', 5], :order => 'diameter ASC'
Cel
Chciałbym mieć coś takiego
has_many :planets, :with_scope => :life_supporting
Edycja: praca wokół
Jak powiedział @phoet, osiągnięcie domyślnego zakresu przy użyciu ActiveRecord może nie być możliwe. Jednak znalazłem dwa potencjalne obejścia. Oba zapobiegają powielaniu. Pierwsza, choć długa, zachowuje oczywistą czytelność i przejrzystość, a druga jest metodą pomocniczą, której wynik jest wyraźny.
class SolarSystem < ActiveRecord::Base
has_many :planets, :conditions => Planet.life_supporting.where_values,
:order => Planet.life_supporting.order_values
end
class Planet < ActiveRecord::Base
scope :life_supporting, where('distance_from_sun > ?', 5).order('diameter ASC')
end
Innym rozwiązaniem, które jest dużo czystsze, jest po prostu dodanie następującej metody do SolarSystem
def life_supporting_planets
planets.life_supporting
end
i używać solar_system.life_supporting_planets
wszędzie tam, gdzie chceszsolar_system.planets
.
Żadne z nich nie odpowiada na pytanie, więc po prostu umieszczam je tutaj, aby obejść tę sytuację, gdyby ktoś inny napotkał taką sytuację.