2010-07-21 3 views
1

사용자, 게임 및 GameView가 있습니다. GameView는 사용자가 본 게임을 설명합니다. 문제는 검토되지 않은 게임을 가져 오기 위해 어떤 조건을 사용해야하는지 파악할 수 없다는 것입니다.has_many "not something": through. 어떤 조건을 사용해야합니까?

class User < ActiveRecord::Base 
    has_many :game_views 
    has_many :unviewed_games, :through => :game_views, :source => :game, ???what conditions??? 
end 

class GameView < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :game 
end 

답변

1

연관이 일반적으로 무언가를 가리키는 외래 키를 가지고 있지만이 경우에는 외래 키가 없기 때문에 나는 이것을 연관으로 보지 않습니다.

def unviewed_games 
    Game.all(:conditions => ["id NOT IN (SELECT game_id FROM game_views WHERE user_id = ?", self.id]) 
end 

당신은 볼 게임을 쿼리하여 NOT IN (1,2,3)을 할 수 있지만, 매우 매우 빠르고, 매우 비효율적 얻을 수 있습니다 : 나는 이렇게 할 것이다 인스턴스 속성을 더으로 이것을 참조하십시오. 이것은 SQL을 작성하는 한 번입니다. 또한 하나 더 할 것입니다 :

이렇게하면 요청의 길이에 대한 인스턴스 변수에 저장하고 여러 개의 데이터베이스 히트를 저장합니다. ||=을 수행 할 수는 있지만 어쨌든 nil을 얻는다면 여전히 데이터베이스를 여러 번 쿼리하게됩니다. 레일즈는 캐싱해야하지만 편집증이라고 부릅니다.

희망이 도움이됩니다.

+0

1. 쿼리에': include' 절을 추가 할 필요가 없습니다. 나는 또한 선언 체크 라인을 제거 할 것이다.''@unviewed_games || = Game.all (...' –

+0

': include'에 대한 좋은 호출인데, 나는 게시물을 쓸 때 쿼리를 변경했다. , 왜냐하면'|| ='는 여전히 데이터베이스를 다시 질의 할 수 있기 때문에'.all'에서는 nil이 발생하지 않아야합니다. 그러나 내 코드가 일관성이 있어야합니다. '|| ='그리고 때때로 선언 검사. –

0

왜 has_many : viewed_games를 보시고 검토하지 않은 게임을 수집하는 별도의 방법을 만드시겠습니까? 나는 has_many에 더 이상 논리를 두는 것을 주저하고 싶다.

0

has_many :through을 사용하여 레일스에서 ​​이러한 방식으로 관계를 표현할 수 없습니다 (또는 적어도 알지 못함). 그러나 :game_views을 기반으로 명명 된 범위를 만들어 원하는 개체를 검색 할 수 있습니다.

나는이 트릭 (안 테스트)를 할 것으로 예상 :

named_scope :unviewed_games, :joins => 'LEFT JOIN game_views ON game_views.game_id = games.id', :conditions => 'game_view_id IS NULL')

관련 문제