다음과 같은 수업이 있다고 가정 해 봅시다.
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
범위 life_supporting
및 SolarSystem
has_many :planets
. 내가 물어 때 그래서 난 내 has_many 관계를 정의하고자하는 solar_system
모든 관련 위해 planets
의 life_supporting
범위가 자동으로 적용됩니다. 기본적으로 solar_system.planets == solar_system.planets.life_supporting
.
요구 사항
-
나는 할 수 없습니다 변경할
scope :life_supporting
에Planet
에default_scope where('distance_from_sun > ?', 5).order('diameter ASC')
-
또한 추가 할 필요없이 중복을 방지하고 싶습니다.
SolarSystem
has_many :planets, :conditions => ['distance_from_sun > ?', 5], :order => 'diameter ASC'
골
나는 같은 것을 갖고 싶다
has_many :planets, :with_scope => :life_supporting
편집 : 해결 방법
@phoet이 말했듯이 ActiveRecord를 사용하여 기본 범위를 달성하지 못할 수도 있습니다. 그러나 두 가지 잠재적 인 해결 방법을 찾았습니다. 둘 다 중복을 방지합니다. 첫 번째는 길지만 분명한 가독성과 투명성을 유지하고 두 번째는 출력이 명시적인 도우미 유형 메서드입니다.
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
훨씬 더 깨끗한 또 다른 해결책은 다음 방법을 추가하는 것입니다. SolarSystem
def life_supporting_planets
planets.life_supporting
end
그리고 solar_system.life_supporting_planets
어디에서나 사용할 수 있습니다 solar_system.planets
.
둘 다 질문에 대답하지 않으므로 다른 사람이 이러한 상황에 직면 할 경우 해결 방법으로 여기에 넣었습니다.
답변
Rails 4 Associations
에는에 scope
적용되는 람다를 허용 하는 선택적 매개 변수가 있습니다 Relation
(참조 : ActiveRecord :: Associations :: ClassMethods에 대한 문서 ).
class SolarSystem < ActiveRecord::Base
has_many :planets, -> { life_supporting }
end
class Planet < ActiveRecord::Base
scope :life_supporting, -> { where('distance_from_sun > ?', 5).order('diameter ASC') }
end
Rails 3 에서는 조건이 다중 또는 해시 (여기에서는 해당되지 않음) 로 정의되는 더 나은 범위를 처리 하는 where_values
방법을 사용하여 해결 방법을 개선 할 수 있습니다 .where_values_hash
where
has_many :planets, conditions: Planet.life_supporting.where_values_hash
답변
Rails 5에서는 다음 코드가 잘 작동합니다.
class Order
scope :paid, -> { where status: %w[paid refunded] }
end
class Store
has_many :paid_orders, -> { paid }, class_name: 'Order'
end
답변
방금 ActiveRecord에 대해 자세히 살펴 보았고 현재 .NET 구현으로 이것이 달성 될 수있는 것처럼 보이지 않습니다 has_many
. 당신은 블록을 전달할 수 :conditions
있지만 이것은 어떤 종류의 영역 물건이 아닌 조건의 해시를 반환하는 것으로 제한됩니다.
원하는 것을 달성하는 정말 간단하고 투명한 방법 (내가하려는 작업)은 런타임에 범위를 적용하는 것입니다.
# foo.rb
def bars
super.baz
end
이것은 당신이 요구하는 것과는 거리가 멀지 만 작동 할 수도 있습니다.)