2011-03-12 2 views
1

나는 HABTM 관계를 가지고있는 사용자와 앨범 모델을 가지고레일 HABTM 쿼리

class Album < ActiveRecord::Base 
    has_and_belongs_to_many :users 

class User < ActiveRecord::Base 
    has_and_belongs_to_many(:albums) 
나는 데이터베이스에 저장되지만 특정과 관련이없는 모든 앨범을 찾으려면

사용자.

Album.all(:order => "albums.created_at DESC", :include => "users", :limit => limit, :conditions => ["users.id != ? AND users.id IS NOT NULL", current_user.id])

하지만 어떤 이유로이 작동하지 않습니다 :

지금까지 내 코드는 다음과 같다. current_user와 연관된 앨범을 반환합니다.

여기 콘솔에서이 출력을 확인하십시오. 첫 번째 가져 오기 사용자 ID를 확인하십시오. 그러면 사용자 ID가 없어야하는 앨범을 가져옵니다. 그런 다음 나열된 앨범 중 하나를 찾고 관련 사용자를 반환하도록 요청하십시오. 해당 사용자 중 하나가 위에서 왔고 있어야합니다. enter image description here

위의 사항을 도와 줄 수있는 사람이 있습니까? 나는 그것이

SELECT * 
FROM albums LEFT OUTER JOIN albums_users ON albums.id = albums_users.album_id 
WHERE albums_users.album_id IS NULL OR albums_users.album_id != #{user_id} 

답변

7

나는 일반적으로 하위 선택을 멀리하려고하지만 난 그것을 다른 방법을 작동시킬 수없는 것 : 당신의 도움에 대한

class Album < ActiveRecord::Base 

    scope :without_user, lambda{|u| where("#{quoted_table_name}.id NOT IN (SELECT `albums_users`.album_id FROM `albums_users` WHERE `albums_users`.user_id = ?)", u.id) } 

end 

user = User.find(30) 
Album.without_user(user) 
+0

@robodisco :이 기능이 작동하지 않습니까? 여기에 뭔가가 명확하지 않나요? Imho 이것이 최고의 대답입니다. – nathanvda

+3

늦게 답장을 보내서 유감스럽게 생각합니다. 일본에 살고있는 최근의 지진과 방사선 두려움은 약간 파괴적이었습니다. 도와 주셔서 감사합니다. 필자는 선택된 대답으로 당신의 것을 표시했습니다. 나는 현상금이 귀하의 것임을 확신하지만 나는 50을 나타내지 만 나타나지는 않습니다. – robodisco

+0

또한 quoted_table_name은 무엇을 참조합니까? – robodisco

1

보십시오 : 당신이 관계 데이터를 보유 할 테이블 albums_users을 만들어 가정

:conditions => ["users.id <> ? AND users.id IS NOT NULL", current_user.id] 
+0

감사합니다. 불행히도 운이 없다, 이것은 결과를 변경하지 않습니다. 그것도 여전히 관련 사용자를 확인할 때 current_user가 표시되는 일부 앨범을 반환합니다. – robodisco

2

SQL 솔루션은 다음과 같습니다.

Album.all.reject{|album| user.albums.include?(album)} 

분명히 데이터베이스에 수십만 개의 행이 있다면이 작업을 원하지 않을 수도 있습니다.

Album.where(["id NOT IN (?)", user.albums_ids]) 

을하지만 사용자가 앨범의 많은 (말을 수백)이있는 경우, 당신은이 작업을 수행해서는 안 :

도 같은 것을 할 수 있습니다.

그 중 하나만 사용하면 쉽게 해결할 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. – robodisco

-1

비의 라인을 따라 SQL을 생성합니다 생각

Album.includes(:users). 
    where(["albums_users.user_id IS NULL OR albums_users.user_id != ?", user_id]) 

:

+0

그래, 그들은 좋은 쉬운 해결책이고 나는 v1을 위해 그들을 위해 갈 것이지만, 많은 경우가 있고 나의 경우에는 사실이있을 때 당신이 거기에 그렇게 좋지 않다고 말했다. – robodisco

+0

전혀 효과가 없습니다 –