2009-09-25 3 views
6

To jest mój pierwszy raz za pomocą szyn i zastanawiałem się, czy to możliwe, aby załadować ma jeden polimorficzny stowarzyszenie w jednym zapytaniu SQL? Modele i związki między nimi są proste wystarczy: model aktywami/tabela może odnosić się do treści (zarówno obraz, tekst lub audio) przez polimorficzny stowarzyszenia, tjMarzą ładowanie polimorficznych stowarzyszeń ActiveRecord

 
class Asset < ActiveRecord::Base 
    :belongs_to :content, :polymorphic => true 
end 

i obraz, tekst, audio są zdefiniowane następująco:

 
class Image < ActiveRecord::Base 
    :has_one :asset, :as => :content 
end 

Kiedy próbuję załadować obraz, powiedzieć tak:

Image.first(
     :conditions => {:id => id}, 
     :include => :asset 
)

określa on dwa zapytania, jeden do pobierania obrazu i inny do pobierania a sset (FYI, dzieje się tak również, jeśli określę :joins). Na podstawie mojego zrozumienia, ActiveRecord robi to, ponieważ nie wie, że istnieje związek jeden do jednego pomiędzy Obrazem i Zasobem. Czy istnieje sposób na wymuszenie połączenia i pobranie 2 obiektów za jednym razem? Próbowałem również używać sprzężenia z niestandardowym wyborem, ale muszę utworzyć ręcznie modele ActiveRecord i ich powiązania.

Czy ActiveRecord zapewnić sposób to zrobić?

Odpowiedz

1

Po wykopaniu przez źródło Rails Odkryłam, że można wymusić poprzez odniesienie dołączyć tabelę innego niż obecny model w obu tych wybranych, warunków lub postanowień porządkowych.

Więc gdybym określić porządek na stole aktywów:

 
Image.first(
     :conditions => {:id => id}, 
     :include => :asset, 
     :order => "asset.id" 
) 

Powstały SQL użyje lewe sprzężenie zewnętrzne i wszystko w jednym sprawozdaniu. Wolałbym wewnętrzne sprzężenie, ale myślę, że to zrobi na razie.

1

Pobiegłem przed tym problemem sam. ActiveRecord pochyla się bardziej w kierunku końca ułatwiając Rubiego (który może nawet nie być zbyt zaznajomieni z SQL) do łączenia się z bazą danych, niż ma to miejsce w optymalnych połączeń baz danych. Może zaistnieć potrzeba interakcji z bazą danych na niższym poziomie (np. DBI) w celu poprawy wydajności. Korzystanie z ActiveRecord z pewnością wpłynie na sposób projektowania schematu.

Pragnienie wydajności SQL dało mi do myślenia o użyciu innych ORMS. Nie znalazłem takiego, który odpowiadałby moim potrzebom. Nawet ci, którzy poruszają się bardziej w kierunku samego SQL transakcyjnego (np. Sequel) mają ciężki API Ruby. Byłbym zadowolony bez API podobnego do Ruby i po prostu ręcznie pisałem mój T-SQL. Prawdziwa korzyść, której szukam z ORM to M, odwzorowujący zestaw wyników (jednej lub więcej tabel) na obiekty.

+0

Zwykle nie używam już ORM-ów. To abstrakcja, bez której bez problemu. – Mario

1

(Jest to dla szyny 3 składni.)

MetaWhere jest niesamowite klejnot do tworzenia złożonych zapytań, które są poza zwykłym domenie ActiveRecord łatwe i ruby-podobnego. (@wayne. Obsługuje zewnętrzne dołącza również)

https://github.com/ernie/meta_where

polimorficzne przyłącza są trochę trudniejsze.Oto jak to zrobiłem kopalnię z MetaWhere:

Image.joins(:asset.type(AssetModel)).includes(:asset) 

W rzeczywistości, zrobiłem metodę wygoda w moim polimorficznych-stowarzyszenia-posiadające klasę:

def self.join_to(type) 
    joins(:asset.type(type)).includes(:asset) 
    end 

tak będzie zawsze zapytać & chętny obciążenia określonego typu aktywów. Nie próbowałem mieszać go z wieloma typami sprzężeń w jednym zapytaniu. Ponieważ polimorfizm działa przy użyciu tego samego klucza obcego, aby odwoływać się do różnych tabel, na poziomie SQL należy określić go jako oddzielne sprzężenia, ponieważ jedno połączenie tylko łączy się z jedną tabelą.

Działa to tylko z ActiveRecord 3, ponieważ masz dostęp do niesamowitej mocy AREL.