Laravel中基于BelongsTo关联实现按品牌名称搜索产品
解决Laravel中关联模型的品牌名称搜索问题
嘿,我来帮你搞定这个品牌名称搜索的需求!你已经搭建好了Product和Brand的belongsTo关联,现在要把品牌名称加入到现有搜索条件里,这里有两种常用的Eloquent写法,都给你整理好了:
方法一:用whereHas关联查询(推荐,符合Eloquent最佳实践)
这种方法利用Eloquent的关联查询能力,不用手动写连表语句,Laravel会自动帮你处理外键关联逻辑:
$products = Product::where('name', 'LIKE', '%' . $searchTerm . '%') ->orWhere('title', 'LIKE', '%' . $searchTerm . '%') ->orWhere('description', 'LIKE', '%' . $searchTerm . '%') ->orWhere('allergies', 'LIKE', '%' . $searchTerm . '%') ->orWhere('price', 'LIKE', '%' . $searchTerm . '%') // 新增品牌名称搜索条件 ->orWhereHas('brand', function ($query) use ($searchTerm) { $query->where('name', 'LIKE', '%' . $searchTerm . '%'); }) ->paginate(15);
orWhereHas的作用是:检查当前Product关联的Brand模型中,是否存在名称包含搜索词的记录,完美匹配你的需求。
方法二:用join连表查询(适合大数据量场景,性能更优)
如果你的产品数据量很大,连表查询的性能会比whereHas更出色,写法如下:
$products = Product::select('products.*') // 只选择products表的字段,避免和brands表字段冲突 ->join('brands', 'products.brand_id', '=', 'brands.id') // 关联品牌表 ->where('products.name', 'LIKE', '%' . $searchTerm . '%') ->orWhere('products.title', 'LIKE', '%' . $searchTerm . '%') ->orWhere('products.description', 'LIKE', '%' . $searchTerm . '%') ->orWhere('products.allergies', 'LIKE', '%' . $searchTerm . '%') ->orWhere('products.price', 'LIKE', '%' . $searchTerm . '%') // 直接查询品牌名称 ->orWhere('brands.name', 'LIKE', '%' . $searchTerm . '%') ->distinct() // 防止连表导致的重复产品记录 ->paginate(15);
注意这里要加select('products.*'),不然如果brands表也有name字段,会覆盖products的name;distinct()是为了避免因为连表产生重复的Product结果。
额外小建议:优化搜索逻辑
如果你的搜索词可能为空,建议用when方法来条件添加搜索条件,避免空搜索时执行全表模糊查询:
$products = Product::query() ->when($searchTerm, function ($query) use ($searchTerm) { $query->where('name', 'LIKE', '%' . $searchTerm . '%') ->orWhere('title', 'LIKE', '%' . $searchTerm . '%') ->orWhere('description', 'LIKE', '%' . $searchTerm . '%') ->orWhere('allergies', 'LIKE', '%' . $searchTerm . '%') ->orWhere('price', 'LIKE', '%' . $searchTerm . '%') ->orWhereHas('brand', function ($query) use ($searchTerm) { $query->where('name', 'LIKE', '%' . $searchTerm . '%'); }); }) ->paginate(15);
这样当$searchTerm为空时,会直接返回所有产品的分页结果,不会执行那些模糊查询条件,性能更友好。
内容的提问来源于stack exchange,提问作者adKB
相关产品推荐
相关产品推荐

