我需要重构我的数据关系,因为包含了日期。我有三种模式:
\App\Product;
discounts()->hasManyThrough('App\Discount', 'App\DiscountProduct', 'product_id','id','id','discount_id');
\App\DiscountProduct;
discount()->belongsTo('App\Discount', 'discount_id');
\App\Discount;
discountProduct()->hasMany('App\DiscountProduct');
当我致电$product->with('discounts')
时
结果是这样的
{"id": 1,
"name": "Wild Blue Shirt",
"discounts": [{
"method": "per_product",
"type": "percentage",
"nominal": 10,
"start_date": "2018-03-01 16:34:50", <= this is my problem
"end_date": "2018-03-31 16:34:50", <= this is my problem
},...other expired discounts],
},...other products
我的问题是:如何过滤每种产品的当前(今天)折扣?
我试过这个:
\App\DiscountProduct;
currentDiscount() {
return $this->belongsTo("App\Discount", 'discount_id')->whereRaw('now() BETWEEN start_date AND end_date');
};
然后
$product->with('discounts.currentDiscount'); <= doesn't worked
这对我有用:
$product_list = $products->with('variants')->with('discounts')->get();
$product_list->transform(function($product) use ($discounts){
$data = $product;
$currentDiscount = collect($product->discounts)->map(function($discount){
$data = null;
if($discount['end_date'] > now()){
$data = $discount;
};
return $data;
});
$data->currentDiscount = $currentDiscount->filter()->first();
return $data;
});
但问题是我无法使用paginate()
功能,使用forpage()
非常痛苦
否则这个原始数据库也可以使用:
$products = DB::table('products')
->selectRaw("products.id, products.name, products.price, COALESCE(active_discount.discount_amount,0) AS discount")
->leftJoin(DB::raw("(discount_products.product_id, CAST(IF(discounts.`type`='percentage', ROUND((discounts.nominal/100)*products.price,0) ,discounts.nominal) AS UNSIGNED) AS discount_amount FROM discount_products JOIN discounts ON discount_products.discount_id=discounts.id JOIN products ON discount_products.product_id=products.id WHERE NOW() BETWEEN discounts.start_date AND discounts.end_date ) active_discount"),'products.id', '=', 'active_discount.product_id'));
我不认为以上所有方法都是最佳解决方案。请帮忙。
答案 0 :(得分:0)
我认为您的问题[与分页/等]是因为您正在制作Raw DB请求而不是使用Eloquent。
约束Eager Loads
有时您可能希望加载关系,但也要指定 急切加载查询的附加查询约束。这是一个 例如:
$users = App\User::with(['posts' => function ($query) { $query->where('title', 'like', '%first%'); }])->get();
在这个例子中,Eloquent只会急切地加载帖子的帖子 标题栏包含第一个单词。当然,你可以打电话给其他人 查询构建器方法,以进一步自定义预先加载 操作:
$users = App\User::with(['posts' => function ($query) { $query->orderBy('created_at', 'desc'); }])->get();
所以在你的情况下,你可以做(没有测试它,但这应该有效):
$product->with(['discounts' => function ($query) {
$query->where(['start_date' , '<', now()] , ['end_date', '>' , now()]);
}])->paginate(10);
您也可以直接在关系中在模型中设置它:
public function currentDiscount()
{
return $this->belongsTo('App\Discount', 'discount_id')
->where(
['start_date', '<', now()],
['end_date', '>', now()]
);
}