Eloquentを使用して、データベースシード中に次のクエリを実行しようとしています。
SELECT
*
FROM
customers
LEFT JOIN
orders
ON customers.id = orders.customer_id
WHERE
orders.customer_id IS NULL
そして、ここにEloquentでの私の実装があります:
$c = Customer::leftJoin('orders', function($join) {
$join->on('customers.id', '=', 'orders.customer_id');
})
->whereNull('orders.customer_id')
->first();
最初のクエリは常に完全な結果を返しますが、Eloquentの同等のものはemail
テーブルのphone
およびcustomers
フィールド以外のすべてに対して常に空の要素を返します。 Customers
モデルとOrders
モデルはどちらも職人が作成したスケルトンなので、これを説明するのに途方に暮れています。
例:
class Customer extends \Eloquent {
// Add your validation rules here
public static $rules = [
// 'title' => 'required'
];
// Don't forget to fill this array
protected $fillable = [];
}
これは、シード(最初はFakerによって生成された)に対する最初のEloquentクエリをdd()したときに出力される配列です。
protected $original =>
array(25) {
'id' =>
NULL
'first_name' =>
NULL
'last_name' =>
NULL
'email' =>
string(24) "[email protected]"
'phone' =>
string(17) "642.150.9176x5684"
'address1' =>
NULL
'address2' =>
NULL
'city' =>
NULL
'state' =>
NULL
'county' =>
NULL
'district' =>
NULL
'postal_code' =>
NULL
'country' =>
NULL
'notes' =>
NULL
'created_at' =>
NULL
'updated_at' =>
NULL
'customer_id' =>
NULL
'total' =>
NULL
}
これは、次のように特定のテーブルから必要な特定の列名を指定することで解決できます。
$c = Customer::leftJoin('orders', function($join) {
$join->on('customers.id', '=', 'orders.customer_id');
})
->whereNull('orders.customer_id')
->first([
'customers.id',
'customers.first_name',
'customers.last_name',
'customers.email',
'customers.phone',
'customers.address1',
'customers.address2',
'customers.city',
'customers.state',
'customers.county',
'customers.district',
'customers.postal_code',
'customers.country'
]);
次のようにselectで列を指定することもできます。
$c = Customer::select('*', DB::raw('customers.id AS id, customers.first_name AS first_name, customers.last_name AS last_name'))
->leftJoin('orders', function($join) {
$join->on('customers.id', '=', 'orders.customer_id')
})->whereNull('orders.customer_id')->first();
クエリをダンプして、実際に実行されたSQLを見て、それが記述した内容とどのように異なるかを確認します。
次のコードでそれを行うことができるはずです。
$queries = DB::getQueryLog();
$last_query = end($queries);
var_dump($last_query);
die();
うまくいけば、何が間違っているのかを理解できる十分な情報が得られるはずです。
私はこれを達成するためにlaravel whereDoesntHaveを使用しています。
Customer::whereDoesntHave('orders')->get();