Я пытаюсь отфильтровать запрос по модели с отношением один ко многим, но это не работает. Правильный вывод должен удалить все запасы с истекшим сроком годности, но он возвращает все доступные запасы.
Товар: hasMany(Stock::class)
Запас: принадлежит(Продукт::класс)
код:
$keyword = $request->keyword;
$data = Product::with('stocks')
->where([
['pharmacy_id', '=', auth()->user()->pharmacy->id],
])
->where(function($productModel) use($keyword) {
$productModel->where('name', 'LIKE', "%$keyword%")->orWhere('sku', 'LIKE', "%$keyword%");
})
->whereHas('stocks', function($stockModel) {
$stockModel->where('expiry', '>', Carbon::now()->format('Y-m-d'));
})->get();
Текущий выход:
[
{
"id": 1,
"sku": "xpzidfa1454995",
"name": "Jaqueline Will",
"category": "medicine",
"type": "manufactured",
"selling_price": "1.00",
"pharmacy_id": 1,
"created_at": "2020-12-22T11:40:32.000000Z",
"updated_at": "2020-12-22T11:40:32.000000Z",
"stocks": [
{
"id": 3,
"product_id": 1,
"expiry": "2025-10-10",
"amount": 40,
"supplier_id": 1,
"pharmacy_id": 1,
"created_at": "2020-12-22T11:45:39.000000Z",
"updated_at": "2020-12-22T11:45:39.000000Z"
},
{
"id": 5,
"product_id": 1,
"expiry": "2020-10-10",
"amount": 40,
"supplier_id": 1,
"pharmacy_id": 1,
"created_at": "2020-12-22T11:45:39.000000Z",
"updated_at": "2020-12-22T11:45:39.000000Z"
}
]
}
]
Правильный вывод:
[
{
"id": 1,
"sku": "xpzidfa1454995",
"name": "Jaqueline Will",
"category": "medicine",
"type": "manufactured",
"selling_price": "1.00",
"pharmacy_id": 1,
"created_at": "2020-12-22T11:40:32.000000Z",
"updated_at": "2020-12-22T11:40:32.000000Z",
"stocks": [
{
"id": 3,
"product_id": 1,
"expiry": "2025-10-10",
"amount": 40,
"supplier_id": 1,
"pharmacy_id": 1,
"created_at": "2020-12-22T11:45:39.000000Z",
"updated_at": "2020-12-22T11:45:39.000000Z"
}
]
}
]
Модель запаса:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Stock extends Model
{
use HasFactory;
protected $fillable = [
'product_id',
'expiry',
'amount',
'supplier_id',
'pharmacy_id',
];
public function pharmacy() {
return $this->belongsTo(Pharmacy::class);
}
public function product() {
return $this->belongsTo(Product::class);
}
}
@Даан, о, ладно, не знал, спасибо! Однако это не решает мою проблему.






Я думаю, вы должны сопоставить дату, используя whereDate.
Попробуй это,
$keyword = $request->keyword;
$data = Product::with('stocks')
->where([
['pharmacy_id', '=', auth()->user()->pharmacy->id],
])
->where(function($productModel) use($keyword) {
$productModel->where('name', 'LIKE', "%$keyword%")->orWhere('sku', 'LIKE', "%$keyword%");
})
->whereHas('stocks', function($stockModel) {
$stockModel->whereDate('expiry', '>', Carbon::now()->format('Y-m-d'));
})->get();
Проверьте эту ссылку, чтобы узнать больше
Дополнительные предложения Laravel Where
Я пробовал это, но это все тот же вывод
Тогда просто используйте now(). Вместо даты форматирования.
Все тот же выход. Я предполагаю, что цепочка предложений where неверна, но я не могу найти правильный способ сделать это.
Чтобы удалить записи о запасах, срок действия которых истек, необходимо наложить ограничение на нетерпеливую загрузку.
$keyword = $request->keyword;
$data = Product::with(['stocks' => fn($query) => $query->whereDate('expiry', '>', now())])
->where([
['pharmacy_id', '=', auth()->user()->pharmacy->id],
])
->where(function($productModel) use($keyword) {
$productModel->where('name', 'LIKE', "%$keyword%")->orWhere('sku', 'LIKE', "%$keyword%");
})
->get();
Это сработало! Вы знаете, хорошо это для производительности или нет?
При нетерпеливой загрузке проблема запроса N+1 избегается. Так что нетерпеливая загрузка на самом деле хороша для производительности. В зависимости от контекста вашего приложения и количества записей для модели продукта вы можете использовать разбиение на страницы вместо выборки всех записей.
Я не думаю, что вам нужно форматировать объект
Carbonв Laravel. Просто используйтеCarbon::now()