2010-10-06 9 views
11

Mam model Author, który habtm: kanały. Używając Rails 3, chcesz ustawić zasięg, który znajdzie wszystkich autorów, którzy nie mają powiązanych kanałów.Jak korzystać z zakresu Rails 3 do filtrowania w tabeli sprzężenia habtm, gdzie powiązane rekordy nie istnieją?

class Author < ActiveRecord::Base 

    has_and_belongs_to_many :feeds 
    scope :without_feed, joins(:feeds).where("authors_feeds.feed_id is null") 

end 

... wydaje się nie działać. Wydaje się to prostą rzeczą. Czego tu mi brakuje?

+0

Czy łączenie (: kanały) wykonuje wewnętrzne sprzężenie, które wybierze tylko autora, jeśli ma źródła danych? – Midwire

+0

To rzeczywiście robi wewnętrzne sprzężenie: "WYBIERZ autorów. * OD autorów INNER JOIN autor_feeds ON authors_feeds.author_id = authors.id INNER JOIN feeds ON feeds.id = authors_feeds.feed_id WHERE (authors_feeds.feed_id ma wartość null)' i co ja pragnienie jest złączeniem zewnętrznym. Jakaś pomoc? – Midwire

Odpowiedz

21

Zgodnie z moją wiedzą ActiveRecord/Arel nie ma możliwości określenia zewnętrznych połączeń. Więc będziesz musiał napisać nieco więcej SQL niż normalnie. Coś jak to powinno załatwić sprawę:

scope :without_feed, joins('left outer join authors_feeds on authors.id=authors_feeds.author_id').where('authors_feeds.feed_id is null') 

Ja oczywiście zgadywania w swoich nazwach tabel i kluczy obcych. Ale to powinno dać ci obraz.

+0

Tak, to zrobiło. Dziękuję Ci! – Midwire

+1

Aby zrobić odwrotność tego (zwróć tylko autorów, którzy mają X), ale za pomocą prostego autora has_many Adresy, to szalone rzeczy (zestawione razem z tego posta i [tego komentarza na blogu] (http://www.bennadel.com/ blog/1093-Uzyskanie jednego rekordu na grupę-z jednego do wielu-Join.htm # komentarzy) wydaje się działać: 'scope: with_address, join (" left external join (wybierz author_id from adresy grup przez autor_id) jako adresy na adresy.author_id = authors.id ") gdzie (" addresses.author_id nie jest pusty ")' – chadoh

+0

@ bioneuralnet, wielkie dzięki –

Powiązane problemy