2010-05-02 2 views
0

나는 세 가지 모델이 있습니다named_scope 또는 find_by_sql?

  • 사용자를
  • 트로피

연관성은 다음과 같습니다

  • 사용자가 많은 상
  • 트로피가 많은 상
  • 있다
  • 수상
  • 수상
  • 사용자 트로피에 속하는 사용자에 속하는 따라서, USER_ID이 상에 FK이며, trophy_id이 상에 FK 인 상

을 통해 많은 트로피를 가지고있다.

STI 모델 인 Trophy 모델에는 trophy_type 열이 있습니다. 특정 트로피를 수상한 사용자 목록을 반환하고 싶습니다. (trophy_type = 'GoldTrophy'). 사용자는 두 번 이상 동일한 트로피를 수상 할 수 있습니다. (뚜렷한 결과는 원하지 않습니다.)

named_scope를 사용할 수 있습니까? 그들을 묶는 건 어때? 아니면 find_by_sql을 사용해야합니까? 어느 쪽이든, 어떻게 코딩합니까?

답변

0

나는 "find_by_sql"로 항상 편안 해요 당신은 내가 "named_scope"을 사용하여 확실하지 않다

User.find_by_sql("select u.id, u.name, t.trophy_type 
        from users u, awards a, trophies t 
        where a.user_id=u.id and 
        t.trophy_id=a.id and 
        t.trophy_type = 'GoldTrophy'" 
       ) 

을 다음과 같이 find_by_sql를 사용하여 그것을 를 사용하지만이

class User < ActiveRecord::Base 

    named_scope :gold_trophy_holder, 
       :select=>" users.id, users.name, trophies.trophy_type",  
       :joins => :awards, "LEFT JOIN awards ON awards.id = trophies.award_id" 
       :conditions => ['trophies.trophy_type = ?', 'GoldTrophy'] 

end 
1
을 시도 할 수 있습니다

named_scope 라우트를 종료하려면 다음을 수행하십시오.

은 has_many 추가 : 사용자 트로피에, 같은 :

has_many :users, :through => :awards 

그리고 다음 named_scope :

named_scope :gold, :conditions => { :trophy_type => 'GoldTrophy' } 

당신은 전화를 할 수있는 사항은 다음과 같습니다

Trophy.gold.first.users 

당신은 호출해야 ' .first '는 named_scope가 콜렉션을 리턴 할 것이기 때문이다. 이상적이지 않습니다. 즉, find_by_sql 또는 named_scope를 사용하지 않는 것이 좋습니다. 좋은 예전을 사용하는 방법 :

Trophy.find_by_trophy_type('GoldTrophy').users 

이것은 정확히 SQL을 파고 들지 않고 원하는대로 할 것입니다.