Laravel结合Carbon实现商品20天内显示New标签的问题
解决商品New标签显示问题
首先,帮你理清两个核心问题的解决方案:
1. 你的原有代码是否正确?
不正确,主要存在两个问题:
- 逻辑方向错误:你写的
where('created_at', '<=', Carbon::now()->subDays(30))是查询创建时间早于30天前的商品,和你需要的「发布后20天内显示New」完全相反。正确逻辑应该是筛选创建时间在20天以内的商品,也就是created_at >= Carbon::now()->subDays(20)。 - 未执行查询:
Product::where(...)返回的是Eloquent查询构造器实例,不是结果集或布尔值,所以直接在Blade里用@if($new)肯定不会生效——它不是一个可判断真假的结果。
2. 如何在Blade模板中编写生效的if语句?
这里分两种推荐方案,取决于你是否使用Eloquent模型:
方案一:使用模型访问器(推荐,代码更优雅)
你之前尝试在模型中添加访问器但报错Undefined property: stdClass::$new,原因是你用DB::table()查询返回的是stdClass对象,而非Product模型实例——模型访问器只对Eloquent模型实例生效。
解决步骤:
第一步:修改控制器查询,使用Eloquent模型
把DB::table()改成Product::开头的查询,确保返回Product模型集合:
$products = Product::join('page-views', 'products.id', '=', 'page-views.visitable_id') ->selectRaw('count(visitable_id) as count, products.*') ->groupBy('products.id') // 明确分组字段,避免MySQL严格模式报错 ->orderBy('count', 'desc') ->having('count', '>=', 100) ->get();
第二步:优化模型访问器
把模型里的访问器改成更简洁的写法:
public function getNewAttribute(): bool { // 判断当前时间距离商品创建时间是否不超过20天 return Carbon::now()->diffInDays($this->created_at, false) <= 20; // 也可以这样写:return $this->created_at->addDays(20)->isFuture() || $this->created_at->addDays(20)->isToday(); }
第三步:在Blade中使用
现在每个$product都是模型实例,可直接访问$product->new属性:
@foreach($products as $product) <div class="product-item"> <!-- 商品其他信息 --> {{ $product->name }} <!-- New标签判断 --> @if($product->new) <span class="new-label">New</span> @endif </div> @endforeach
方案二:直接在Blade中判断(无需修改模型)
如果你暂时不想改成Eloquent查询,也可以直接在Blade中对每个商品的创建时间进行判断:
@foreach($products as $product) <div class="product-item"> {{ $product->name }} @if(Carbon\Carbon::parse($product->created_at)->diffInDays(Carbon\Carbon::now()) <= 20) <span class="new-label">New</span> @endif </div> @endforeach
注意:因为DB::table()返回的created_at是字符串,所以需要用Carbon::parse()转换成Carbon实例后再进行日期计算。
内容的提问来源于stack exchange,提问作者mafortis
相关产品推荐
相关产品推荐

