Я пытался заставить мои модели хорошо играть с агрегированным выражением в Laravel (4.2), но безрезультатно. Когда я использую ‘join’, вложенная структура json очищает свои записи. Он основан на кредитах и платежах.
Вот упрощенная схема:
платежи: id | loan_id | платный | ожидаемый
кредиты: id | collectiontype_id | principal_amount
Мне нужно выяснить, есть ли задолженность по счету и сколько, а также просмотреть прошлые платежи.
Вот модели:
Loan.php
public function payment()
{
return $this->hasMany('Payment');
}
Payment.php
public function loan()
{
return $this->belongsTo('Loan');
}
Выполнение следующих действий дает мне все данные, необходимые для платежей:
Loan::with('collectiontype','payment')->get();
В какой-то момент у меня было следующее в модели займа:
public function payAggregate()
{
return $this->hasOne('Payaggregate','loan_id','id')
->select(DB::raw("loan_id, count(*) as count, sum(expected) as sumexpected, sum(paid) as sumpaid, (sum(expected) - sum(paid)) as arrears"))
->groupBy('loan_id')
->having('arrears','>',10);
}
Который хорошо работал в изоляции. Тем не менее, когда я попытался сделать «с»:
Loan::with('collectiontype','payment','payaggregate')->get();
Он работал без оговорки, но не с. Я пробовал «есть», «где есть» и много странных и замечательных вещей, но ни одна из них, похоже, не работает для меня.
Затем я подумал о создании вручную с помощью соединений:
$v= DB::table('loans AS l')
->select(array('l.*', 'p.arrears','ct.shortlabel','pay.paid', 'pay.expected'))
->join(DB::raw('(SELECT loan_id, count(*) as count, sum(expected) as sumexpected, sum(paid) as sumpaid, (sum(expected) - sum(paid)) as arrears FROM payments GROUP BY loan_id) AS p'), function( $query ){
$query->on( 'l.id', '=', 'p.loan_id' );
})
->join(DB::raw('(SELECT * FROM collectiontypes) AS ct'), function( $query ){
$query->on( 'l.actualcollection', '=', 'ct.id' );
})
->join(DB::raw('(SELECT * FROM payments) AS pay'), function( $query ){
$query->on( 'l.id', '=', 'pay.loan_id' );
})
->where('p.arrears', '>', 10)->paginate(30);
$v->getCollection()->toJson();
Однако это только дало плоский вывод без вложенного объекта платежей. Я надеюсь, что ясно сформулировал проблему.
Задача ещё не решена.
Других решений пока нет …