Laravel: поиск связей с условиями и извлечение записей

#php #laravel #eloquent #laravel-query-builder

#php #laravel #красноречивый #laravel-конструктор запросов

Вопрос:

У меня есть несколько связанных таблиц в школьной базе данных. У меня есть Student, StdAct и транзакции. У студента есть учетная запись за каждый год. Таким образом, у учащегося может быть много учетных записей (в зависимости от года и оценки). Например: студент (id: 2) может иметь следующие учетные записи

  • StdAct (id: 10, student_id: 2, год: 2018, класс: 10-й)
  • StdAct (id: 23, student_id: 2, год: 2019, класс: 11)
  • StdAct (id: 53, student_id: 2, год: 2020, класс: 12-й).. И так далее.

У StdAct может быть много транзакций. Например, StdAct (идентификатор: 10, год: 2018, класс: 10th) может содержать следующие транзакции:

  • Tran (id: 110, act_id:10, Сумма: 20 $, Created_at: 2020-10-10)
  • Tran (id: 340, act_id:10, Сумма: 40 $, Created_at: 2020-11-10).. И так далее.

Я хотел бы распечатать такой отчет:

Std_name элемента Tran(сумма) Дата

  • 1 Джон 20 $ 2020-10-10
  • 2 Джон 40 $ 2020-11-10
  • 3 Деннис 44$ 2020-11-02

И так далее..

Учитывая (год и класс), я хотел бы выполнить поиск и найти все стандартные данные со связанными транзакциями и именами связанных учащихся на основе данных, введенных пользователем (год и класс).

Мне также может потребоваться сгенерировать один и тот же отчет на основе заданных двух дат (вводимых пользователем). Итак, я бы искал транзакции между двумя заданными датами и находил связанные StdActs и Students (нам нужно std_name).

Вот мои модели

 class StdActs extends Model
{
    //
    protected $table = 'StdActs';

    public function student()
    {
        return $this->belongsTo('AppStudents', 'student_id');
        //return $this->belongsTo('AppStudents', 'id');
    }


    public function transactions()
    {
        return $this->hasMany('AppTransactions','act_id');
    }

}

class Students extends Model
{
    protected $table ='Students';

    public function StdActs()
    {
        return $this->hasMany('AppStdActs', 'student_id', 'id');
    }
}

class Transactions extends Model
{
    protected $table = 'Transactions';

    public function StdAct()
    {
        return $this->belongsTo('AppStdActs');
    }
}
  

Примечание:
Я пробовал некоторые похожие случаи (но не тот случай, о котором я спрашивал выше), например, следующее:

 $stdActs = StdActs::whereHas('student', function($query){
    $query->where ('std_name', 'like' , '%' . request ( 'keywords'   ) . '%');
    })
    ->where('year_id'  , '=', request ( 'year'   ) )
    ->where('school_id', '=', request ( 'school' ) )
    ->get();
  

Однако он возвращает только стандартные значения.. Нет имени студента..
Если здесь можно получить std_names; тогда я думаю, мы можем решить исходную проблему.

Ответ №1:

Ваш исходный запрос ограничен экземплярами, которые соответствуют требованиям, но вы не просите загружать отношения. whereHas() StdActs Это делается с помощью with() метода, а затем мы ограничиваем его теми же требованиями, что и раньше.

 $key     = '%' . request('keywords') . '%';
$year    = request('year');
$school  = request('school');

$stdActs = StdActs::where('year_id', $year)
    ->where('school_id', $school)
    ->whereHas('student', fn ($q) => $q->where('std_name', 'like' , $key))
    ->with(['student' => fn ($q) => $q->where('std_name', 'like' , $key)])
    ->get();
  

Комментарии:

1. Большое вам спасибо @miken32 !. Это работает нормально. Я добавил некоторый код для выбора некоторых столбцов из таблицы ‘student’. Вот что у меня есть: ->with( [ ‘student’ => function($query) { $query ->где(‘std_name’, ‘like’, ‘%’ . запрос (‘ключевые слова’) . ‘%’) ; } ] )-> с помощью ( ‘student:id,std_name’)