2014-04-05 7 views
7

Mam następujące trzy modele join-relacjęRails Dołącz Wybór modelu wspólnych kolumn

class Book < ActiveRecord::Base 
    has_many :contributions, :dependent => :destroy 
    has_many :contributors, :through => :contributions 
end 

class Contributor < ActiveRecord::Base 
    has_many :contributions, :dependent => :destroy 
    has_many :books, :through => :contributions do 
    def this_is_my_contribution(book, join_attrs) 
     Contribution.with_scope(:create => join_attrs) {self << book} 
    end 
    end 
end 

class Contribution < ActiveRecord::Base 
    belongs_to :book 
    belongs_to :contributor 
end 

Następnie po wstawieniu rekordów do wkładu model, postanowiłem chcę zrobić kwerendę na tym modelu, aby pobrać wszystkie książki i Współpracownicy nazwiska jak kwerendy wynik jak na poniższym SQL równoważnej

SELECT Contributions.*, Contributors.name, Books.name from Contributions 
INNER JOIN Contributors ON Contributors.id = Contributions.contributors_id 
INNER JOIN Books ON Books.id = Contributions.books_id 

Ale w IRB konsoli, gdy to pisałem,

Contribution.joins(:contributor, :book).select("contributors.name, books.name, 
    contributions.*") 

uzyskać następujące dane wyjściowe zamiast

Contribution Load (0.8ms) SELECT contributors.name, books.name, contributions.* FROM 
"contributions" INNER JOIN "contributors" ON "contributors"."id" = 
"contributions"."contributor_id" INNER 
JOIN "books" ON "books"."id" = "contributions"."book_id"                                   
=> #<ActiveRecord::Relation [#<Contribution id: 1, book_id: 1, contributor_id: 1, role: 
"author", created_at: "2014-04-04 00:19:15", updated_at: "2014-04-04 00:19:15">, # 
<Contribution id: 2, book_id: 2, contributor_id: 2, role: "Author", created_at: "2014- 
04-05 06:20:34", updated_at: "2014-04-05 06:20:34">]> 

nie dostanę żadnej książki nazwę i nazwę specjalista w oparciu o sprzężenie wewnętrzne kluczy obcych.

Nie mogłem zrozumieć, w jaki sposób instrukcja SQL RAILS jest bardzo zła, kiedy tego chcę.

Co to w pełni rozumiem?

Odpowiedz

5

Modele prowadnic są mapowane z powiązanymi tabelami, więc po wysłaniu zapytania do tego modelu zwraca model modeli, który w tym przypadku jest modelem Contribution, który nie ma innych atrybutów modelu, aby osiągnąć to, co chcesz, musisz wpisać zapytanie jak

contributions = Contribution.joins(:contributor, :book).select("contributors.name 
    as c_name, books.name as b_name, contributions.*") 

zwrócony wynik będzie tablicą treści i można dostać nazwę książki od wyniku przez atrybut b_name jak

contributions.last.b_name 

Uwaga: w zależności od tego, jak masz zamiar użyć wyników zapytania trzeba c hoose między joins i includes można odczytać Here

+0

Dzięki Sat's. Przepraszam za moją spóźnioną odpowiedź. Nie mam możliwości wypróbowania powyższego kodu. Ale po przeczytaniu linku podanego powyżej, staje się dla mnie bardziej krystalicznie jasne, dlaczego konieczne jest podjęcie takich kroków. Dzięki jeszcze raz! – awongCM

0

Tak, w odpowiedzi na zapytania przyzwyczajenie zobaczyć dowolną nazwę książki, jednak jeśli nie wynikają [0] .book.name, widać nazwę książki. Po prostu nie jest widoczny w wyświetlanym wyniku, ale możesz go uzyskać, uzyskując dostęp do niego.

Jak powiedział sat, możesz użyć include, aby nie tworzył dodatkowej kwerendy, gdy uzyskasz dostęp do tabeli książek, jednak w złączeniu wykona dodatkowe wywołanie DB dla każdego dostępu do tabeli książek.

+0

Dzięki za to. Chociaż muszę przyznać. Nie bardzo mi się podobało, gdy zobaczyłem, jak mój kod nie mógł pobrać wyników, o czym wyraźnie powiedziałem, zanim zrobiła coś, o tym, jak używać złączeń, wybiera i zawiera. Da mi szansę na kolejny projekt. Twoje zdrowie! – awongCM