2009-09-25 71 views
6

這是我第一次使用Rails,我想知道是否有可能在一個SQL查詢中加載一個多態關聯?這些模型和它們之間的關聯是基本夠用了:一個資產模型/表可以參考內容(無論是圖片,文字或音頻)通過一個多態關聯,即在ActiveRecord中急切加載多態關聯

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

和圖片,文字,音頻這樣的定義:

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

當我嘗試加載圖像,這樣說:

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

它指定了兩個查詢,來檢索圖像和其他檢索在A sset(FYI,如果我指定:joins,也會發生這種情況)。基於我的理解,ActiveRecord這樣做是因爲它不知道Image和Asset之間存在一對一關聯。有沒有辦法強制加入並一次檢索2個對象?我也嘗試使用自定義選擇連接,但我最終不得不手動創建ActiveRecord模型及其關聯。

ActiveRecord是否提供了一種方法來執行此操作?

回答

1

在挖掘了Rails源代碼之後,我發現您可以通過在select,conditions或order子句中引用除當前模型以外的表來強制連接。

所以,如果我指定的資產表中的順序:

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

生成的SQL會使用一個左外連接,並在一個聲明中的一切。我本來希望有一個內部連接,但我想現在會這樣做。

1

我碰到了這個問題我自己。 ActiveRecord更傾向於使Rubyists(可能甚至不太熟悉SQL)與數據庫接口相比,更容易實現與優化數據庫調用的接口。您可能必須與較低級別的數據庫(例如DBI)交互以提高性能。使用ActiveRecord一定會影響你如何設計你的模式。

對SQL效率的渴望讓我想到了使用其他ORM。我沒有找到適合我需要的人。即使那些更傾向於交易SQL本身的應用(例如Sequel)也有一個沉重的Ruby API。我會滿足於沒有類似Ruby的API,只是手動編寫我的T-SQL。我用ORM得到的真正好處是M,將結果集(一個或多個表)映射到對象中。

+0

我通常不再使用ORM。這是一個抽象,我沒有做得很好。 – Mario

1

(這是爲Rails 3語法。)

MetaWhere是用於製造複雜的查詢是ActiveRecord的通常的域容易和紅寶石等的室外一個真棒寶石。 (@wayne:它支持外部聯接以及)

https://github.com/ernie/meta_where

多態連接是有點麻煩。下面是我如何做礦用MetaWhere:

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

事實上,我在多態有關聯級做了一個方便的方法:

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

所以它總是會詢問&渴望負荷提供特定類型的資產。我沒有嘗試在一個查詢中將它與多種類型的連接混合。因爲多態性使用相同的外鍵來引用不同的表,所以在SQL級別上,您必須將其指定爲單獨的連接,因爲一個連接只能連接到一個表。

這隻適用於ActiveRecord 3,因爲您可以使用AREL的驚人力量。