#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. Проверьте обновление. Здесь показано, как настроить приведения для вашей модели