laravel, который месяц не работает в коллекции

#php #mysql #laravel #eloquent

#php #mysql #laravel #красноречивый

Вопрос:

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

Я использовал whereHas вместо инициализации коллекции, но это становится очень длинным кодом, который все еще можно сократить до более эффективного.

 $makati = [];
        $cebu = [];
        $davao = [];

        for($x = 1; $x <= 12; $x  ){
            $makati[$x-1] = student::with('branch', 'program')
                ->whereHas('branch', function($query){
                    $query->where('name', '!=', 'Language Only');
                })
                ->whereHas('branch', function($query) {
                    $query->where('name', 'Makati');
                })->whereMonth('date_of_signup', $x)->whereYear('date_of_signup', '2019')->count();
        }
  

Это работает отлично, но посмотрите, что я сделаю тот же код для массивов $ cebu и $ davao.

 $student = student::with('branch', 'program')->whereYear('date_of_signup', '2019')->get();
        $student = $student->where('program.name', '!=', 'Language Only');
        $makati = [];
        $cebu = [];
        $davao = [];

        for($x = 1; $x <= 12; $x  ){
            $makati[$x-1] = $student->whereMonth('date_of_signup', $x);
            info($makati);
        }
  

Я пробовал этот, но именно здесь возникает ошибка whereMonth.

первый код действительно работает, но я хочу сделать более короткий и эффективный код.

Ответ №1:

     $student = student::with('branch', 'program')->whereYear('date_of_signup', '2019');
    $student = $student->where('program.name', '!=', 'Language Only');
    $makati = [];
    $cebu = [];
    $davao = [];

    for($x = 1; $x <= 12; $x  ){
        $makati[$x-1] = $student->whereMonth('date_of_signup', $x)->get();
        info($makati);
    }
  

Я думаю, что метод whereMonth () работает не на полученном экземпляре коллекции, а на экземпляре построителя запросов, поэтому получение коллекции делает метод недоступным. как и код, который я скопировал выше, не получайте, пока не закончите использовать все конструкторы запросов. Я надеюсь, что это поможет.

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

1. каков ваш ответ? whereMonth по-прежнему возвращает ошибку?

2. сейчас это не whereMonth, это из-за get, он ничего не возвращает, если я не использую get в первой строке.

Ответ №2:

whereMonth('x', 1) это ярлык, который генерирует SQL WHERE MONTH(x)=1 . Запросы SQL обычно не сопоставляются с коллекцией, даже несмотря на то, что предпринимаются усилия по максимально возможному сопоставлению методов коллекции с методами построения запросов. Обходной путь заключается:

 $student = student::with('branch', 'program')->whereYear('date_of_signup', '2019')->get();
$student = $student->where('program.name', '!=', 'Language Only');
$makati = [];
$cebu = [];
$davao = [];

for($x = 1; $x <= 12; $x  ){
    $makati[$x-1] = $student->filter(function ($value) use ($x) {
         return $value->date_of_signup->month == $x;
    });
    info($makati);
}
  

Это предполагает, что date_of_signup это правильно приведено к дате при извлечении с использованием $dates свойства в модели.

Это делается в вашей student модели:

  class student extends Model {
     protected $casts = [ 'date_of_signup' => 'date' ]; 
     // rest of model
 }
  

В качестве примечания, вероятно, будет эффективнее, если вы сделаете:

 $student = student::with('branch', 'program')
          ->whereYear('date_of_signup', '2019')
          ->whereHas('program' => function ($query) {
               $query->where('name', '!=', 'Language Only');
          })
          ->get();
  

который будет фильтровать результаты с помощью SQL-запроса вместо того, чтобы получать все, а затем фильтровать по коллекции

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

1. date_of_signup фактически уже является столбцом даты в таблице student. ни одно из решений не будет работать для меня.

2. Почему это не сработало бы? Вы можете задать столбец даты, который будет приведен к Carbon экземпляру в вашей модели

3. там говорится, что я пытаюсь получить месяц не-объекта. что касается 2-го решения, where не работает на with. это должно быть wherehas.

4. Проверьте обновление. Здесь показано, как настроить приведения для вашей модели