2016-07-13 6 views
2

ジャンクション(スライダイメージ)テーブルに関連する2つのテーブル(スライダ、イメージ)がありますが、関係はうまく動作しますが、特定の順序で関連するデータを取得するために、私は画像をforeachの使用して、正しい画像が、間違った順序を受け取る$model->imagesを呼び出すが、私は得ることができますどのように、idで命じられたときYii2多対多関係の注文項目

public function getImages(){ 
    return $this->hasMany(Images::className(), ['id' => 'image_id']) 
     ->viaTable('sliders_images', ['slider_id' => 'id'], function($query){ 
      $query->orderBy('sliders_images.display_order ASC'); 
     }); 
} 

:右の順序は、接合テーブルで、関係は次のように定義されています他の属性によって順序付けられた画像?

答えて

0

この場合orderByは、最初のクエリ(SELECT * FROM sliders_images ...)に適用されますので、あなたは、生成されたSQLをチェックします場合:

echo $model->getImages()->createCommad()->rawSql; 

を、あなたはこの

SELECT * FROM images WHERE id IN (4, 2, 3, 1) 

のようなものが表示され、ここで正しい順序になります。しかし結果セットでは、あなたはid(1,2,3,4)によって注文を受けました。

だから、正しい順序を取得するには、あなたのhasManyに希望orderByを追加する必要があります

public function getImages(){ 
    return $this->hasMany(Images::className(), ['id' => 'image_id']) 
    ->viaTable('sliders_images', ['slider_id' => 'id']) 
    ->orderBy(['images.display_order' => SORT_ASC]); 
} 

関連トピック:ActiveRecord where and order on via-table

+0

Korshunow再生のおかげで、あなたの提案は正しい方法ではなく、解決策を見つけるために私の心を開きます。表イメージにはdisplay_order属性がありません。これはジャンクション表属性です。私は 'joinWith()'ステートメントが必要です。正しい答えに従います。 – MarBer

+1

ああ、それを逃した)あなたは正しい。実際には、私は常に、すべてのテーブルに対して分離されたARエンティティを宣言し、関係やクエリで直接テーブル参照の代わりに 'via'と' joinWith'を処理する方が好きです。このアプローチは、よりクリーンで柔軟で持続可能なコードIMHOにつながります。だから間違いなく正しい方法で) – oakymax

1

を正しい方法で取得ジャンクションテーブル用ジャンクションテーブル->joinWith('slidersImages')と結合を追加することですそれらの属性の1つによって順序付けされる。完全なコード:

public function getImages(){ 
     return $this->hasMany(Images::className(), ['id' => 'image_id']) 
     ->via('slidersImages') 
     ->joinWith('slidersImages SI') 
     ->orderBy('SI.display_order ASC'); 
}