Railsを使用するのはこれが初めてで、をロードすることが可能かどうか疑問に思う1つのSQLクエリに1つのポリモーフィックな関連付けがありますか?モデルとそれらの間の関連付けは十分に基本的です:アセットモデル/テーブルは、多型の関連付け、すなわち
クラスAsset <ActiveRecord :: Base :belongs_to:content、:polymorphic => true 終わり
画像、テキスト、音声は次のように定義されます。
クラスImage <ActiveRecord :: Base :has_one:asset、:as =>:content 終わり
画像をロードしようとすると、次のように言います:
Image.first( :conditions => {:id => id}、 :include =>:asset )
2つのクエリを指定します。1つは画像を取得し、もう1つはアセットを取得します(FYI。これは、 :joins
)。 私の理解に基づいて、ActiveRecordがこれを行うのは、ImageとAssetの間に1対1の関連付けが「存在しない」ためです。一度に強制的に結合し、2つのオブジェクトを取得する方法はありますか?また、カスタム選択で結合を使用しようとしましたが、最終的にActiveRecordモデルとその関連付けを手動で作成する必要があります。
ActiveRecordはこれを行う方法を提供しますか?
回答:
回答№1は1Railsソースを掘り下げた後、select、conditions、order句のいずれかで現在のモデル以外のテーブルを参照することで強制的に結合できることを発見しました。
したがって、Assetテーブルで注文を指定すると:
Image.first( :conditions => {:id => id}、 :include =>:asset、 :order => "asset.id" )
結果のSQLは、1つのステートメントで左外部結合とすべてを使用します。私は内部結合を好んでいましたが、今のところこれでうまくいくと思います。
回答№2の場合は1
私は自分でこの問題に立ち向かった。 ActiveRecordは、最適化されたデータベース呼び出しよりも、Rubyist(SQLにあまり慣れていない人でも)がデータベースと簡単にやり取りできるようになるという傾向にあります。パフォーマンスを改善するために、より低いレベルのデータベース(DBIなど)と対話する必要がある場合があります。 ActiveRecordを使用すると、スキーマの設計方法に確実に影響します。
SQLの効率性に対する欲求が私を考えさせました他のORMの使用について。私は自分のニーズに合ったものを見つけませんでした。トランザクションSQL自体に向かったもの(例:Sequel)でも重いRuby APIを持っています。 ORMを使用した後の本当のメリットはMです。結果セット(1つまたは複数のテーブル)をオブジェクトにマッピングします。
回答№3の場合は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レベルでは1つのテーブルのみに結合するため、個別の結合として指定する必要があります。
ARELの驚くべきパワーにアクセスできるため、これはActiveRecord 3でのみ機能します。