Laravel 10:Eloquent关联预加载如何排除$append属性?
在Eloquent关联预加载时排除$append附加属性的方法
当然可以,下面是几种实用的解决办法:
1. 临时清空关联模型的$appends
在预加载的闭包中,直接修改关联模型的$appends属性,让它在本次查询中不附加任何额外属性:
public static function adminTableData(): Builder { return self::query()->select('*') ->with(['category' => function($query) { // 临时移除关联模型的所有附加属性 $query->getModel()->setAppends([]); return $query->select('id', 'name'); }]); }
如果只想保留部分附加属性,给setAppends()传指定数组即可,比如setAppends(['only_this_one'])。
2. 用makeHidden()隐藏指定附加属性
如果只是想隐藏特定的几个附加属性,而非全部,可以在查询结果中对关联模型实例调用makeHidden():
// 获取数据后处理 $products = Product::adminTableData()->get()->each(function($product) { $product->category->makeHidden(['admin_table_logo', 'edit', 'remove']); });
也可以在预加载闭包里提前设置隐藏属性,让查询出来的模型直接隐藏这些字段:
->with(['category' => function($query) { $query->select('id', 'name') ->getModel()->setHidden(['admin_table_logo', 'edit', 'remove']); }])
3. 自定义模型方法控制输出
如果需要频繁排除这些附加属性,可以在模型里写一个自定义方法,只返回原始数据库字段:
// 在目标关联模型中添加 public function toRawArray() { // 只返回数据库原始属性,不包含附加属性 return $this->attributesToArray(); }
之后在获取数据时调用这个方法:
$products = Product::adminTableData()->get()->map(function($product) { $product->category = $product->category->toRawArray(); return $product; });
4. 使用资源类(推荐用于API场景)
如果是给API返回数据,Laravel的资源类是更规范的方式,能精准控制输出字段,自动排除附加属性:
// 创建ProductCategoryResource类 class ProductCategoryResource extends JsonResource { public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, ]; } }
返回时用资源包装:
return ProductCategoryResource::collection($products->pluck('category'));
内容的提问来源于stack exchange,提问作者Sasha
相关产品推荐
相关产品推荐

