0

Activityモデルを参照するモデルがありますType

次に、Scheduleを参照する可能性のあるモデルがありますActivity

そのため、アクティビティの種類に基づいてスケジュールをクエリしたい場合があります (これは NULL の可能性がありますが、それは関係ありません。... のLEFT JOIN代わりに aが必要なだけJOINです)。

Laravel4 の Eloquent を使用すると、スコープを作成して(ここではネガティブスコープが必要です)、次のように記述できます。

Schedule::where(...)->notOfType(myType)->...

熱心な読み込みの制約を使用しようとすると、あまりにも厄介であることが判明しました

Schedule::with(array('activities' => function($query)
{
    $query->where('activity_description', 'like', '%lots of lulz%');
}))->get();

...ここでは、 の属性Activity、直接関連するモデルでScheduleはなく、の属性に対してクエリを実行しているためですTypewith古き良きJOINに目を向ける前に、ネストされたsのいくつかのバージョンを試しました。

public function scopeNotOfType($query, $type) {
    $query  
    ->leftJoin('activities',     'schedule.activity_id', '=', 'activities.id')
    ->leftJoin('activity_types', 'activities.type_id',   '=', 'activity_types.id')
    ->where('activity_types.name', '!=', $type->name);
}

activity_id に基づいてアクティビティをスケジュールに結合し、次にtype_id に基づいてタイプをアクティビティに結合することを意味します。その時点で、私の選択条件は型の名前フィールドで実行されます。

エラーはなく、非常に単純なデータでも機能しましたが、詳しく調べると、データがすべて間違っていることがわかりました。クエリが実行され、SQL アナライザーを使用した単純な (単純すぎる!) チェックでは、予想されるデータが返されていることがわかりましたが、Eloquent モデルからは消えてしまいました

何が起こっているのかについての最初のヒントは、フィルターによって取得されると、シードされたが、予想される「スケジュール」ではなく「タイプSchedule(1)説明」の説明フィールドを持っているように見えたことです。 (1)説明」。

複数のモデルに同じ名前のフィールドが存在するときはいつでも、 からではなく間違ったモデルから値を取得していましたScheduleあはは。実はLaravel4はPHPで、SQLのフィールドを順番に配列として取得しており、上記のsでSELECT生成されたのはこんな感じだったので、JOIN

+----------------+-------------+---------+-------------+
| schedule_id    | description | type_id | description |
+----------------+-------------+---------+-------------+
| 1              | Sched_Desc  | 1       | Type_Desc   |
| 2              | Sched2_Desc | 7       | Type7_Desc  |
+----------------+-------------+---------+-------------+

...PDO ドライバーがフィールド値を取得したとき、 の最後のインスタンス、上記の 4 番目の列descriptiontypeの説明が、2 番目のスケジュールの説明を上書きしました。

4

1 に答える 1

1

ソリューション I

明らかな解決策は、必要なフィールドのみを選択することでした。ここで私はスコーピングScheduleを行っており、関連するモデルをあまり気にすることができなかったので、Scheduleフィールドを次のように指定しましたselect():

public function scopeNotOfType($query, $type) {
$query 
    ->leftJoin('activities',     'schedule.activity_id', '=', 'activities.id')
    ->leftJoin('activity_types', 'activities.type_id',   '=', 'activity_types.id')
    ->select('schedule.*')
->where('activity_types.name', '!=', $type->name);
}

...そして、Scheduleフィールドのみが取得され、フィールド名の競合はなくなりました。

ソリューション II

もう1 つの解決策は、フィールド自体にテーブル名をエンコードすることactivity.activity_descriptionです。しかし、それはさらにぎこちなく感じられ、常に便利であるとは限りません.activity_description<something-else>_description

于 2013-10-06T20:41:38.853 に答える