2011-02-01 2 views
11

그래서 나는 포함 된 협회에 스코프를 적용하고 싶다는 미친 생각을 가지고 있습니다. 이것이 내가 알아 낸 것인데, 잘 작동하는 것 같습니다 :어소시에이션에서 스코프 사용

class Event < ActiveRecord::Base 
    has_many :races 
    has_many :bad_races, :conditions => Race.bad_medals_sql, :class_name => "Race" 
end 

class Race < ActiveRecord::Base 
    def self.bad_medals_sql 
    arel_table[:prizes].eq('medals').to_sql 
    # This returns a string 
    # "`races`.`prizes` = 'medals'" 
    end 

    def self.bad_medals 
    where(bad_medals_sql) 
    end 
end 

Event.includes(:bad_races) 
Reloading... 
    Event Load (0.4ms) SELECT `events`.* FROM `events` 
    Race Load (0.5ms) SELECT `races`.* FROM `races` WHERE (`races`.event_id IN (1,2,3,4) AND (`races`.`prizes` = 'medals')) 

문제는 정말 무모하다는 것입니다. 레이스 (다른 곳에서 사용하기 위해)에 정의 된 범위를 가지고 이벤트 협회에서 사용하려면 레이스에 두 가지 방법이 있어야합니다. 각 범위.

필자는 패턴을 플러그인 또는 일부 랩핑 할 수 있다고 확신하지만 가능하다면 원시 AR/ARel을 사용합니다. 그 일을하기위한 아이디어가 있습니까?

답변

6

이 코드는 지나치게 복잡합니다. 당신의 목표가 상품에 대한 "메달"만있는 경주가 포함 된 모든 이벤트를 얻는 것이라면 단순한 scope이 작동하지 않을까요?

나쁜 종족을 얻으려면 Event.bad_races을 실행하면됩니다.

scope :bad_races, -> { joins(:races).where(races: { prizes: 'medals' }) } 
+7

"그래서 내가 포함 된 협회에 범위를 적용하고 싶다는 미친 생각이 들었습니다." – jsharpe

+2

AFAIK 당신은'Race'에서'bad'를 스코프로 만들어서이 코드를 지우고'races.bad'라고 말하십시오. 아니면 범위와 만 작동 할 수 있습니다. ( –

+1

@AlexeiAverchenko 그러나이 경우 조건을 충족하는 경주가있는 이벤트를 원합니다 (예 : 레이스 개체를 원할뿐만 아니라 이벤트 개체를 원함). 그들은에 속한다). –

0

A는 더 연결의 범위를 표현하는 최신 방법까지 다음과 같다. 이 경우에 매우 편리합니다.

class Event < ActiveRecord::Base 
    has_many :races 
    scope :bad_races, -> { joins(:races).merge(Race.bad_medals) } 
end 

class Race < ActiveRecord::Base 
    belongs_to :event 
    scope :bad_medals, -> { where(price: 'medal') } 
end 
0

당신은 merge 방법 두 모델에 범위를 사용할 수 있습니다