Laravel中如何获取关联日志不含特定状态的Invoice模型数据
解决Laravel中筛选无特定状态发票日志的问题
你当前的查询逻辑跑偏啦!whereHas的作用是只要发票存在至少一条符合条件的关联日志,就会被选中。但发票16虽然有delivered和returned的日志,同时也有processing、shipped这类符合你原查询条件的日志,所以它会被错误地包含进来。
我们真正需要的逻辑是:该发票的所有关联日志里,完全不存在delivered或returned这两种状态,推荐两种简洁的实现方式:
方法一:使用whereDoesntHave(最直观)
这个方法专门用来筛选「不存在符合指定条件的关联模型」的主模型,完美匹配你的需求:
$invoices = Invoice::whereDoesntHave('logs', function ($query) { $query->whereIn('invoice_status', ['delivered', 'returned']); })->get();
这段代码会直接过滤掉所有拥有delivered或returned状态日志的发票,剩下的就是你要的ID 17和18。
方法二:使用whereHas结合数量判断
如果你更习惯用whereHas的写法,可以通过统计符合负面状态的日志数量,要求数量为0:
use Illuminate\Support\Facades\DB; $invoices = Invoice::whereHas('logs', function ($query) { $query->select(DB::raw('count(*) as bad_status_count')) ->whereIn('invoice_status', ['delivered', 'returned']); }, '=', 0)->get();
这里的第三个参数=和第四个参数0表示:符合「状态是delivered/returned」的日志数量必须为0,同样能得到正确结果。
再回头看你原来的代码,where('invoice_status','!=', 'delivered')->where('invoice_status','!=', 'returned')其实是在找「状态既不是delivered也不是returned」的日志,但只要发票有一条这样的日志就会被选中——这显然不是你想要的逻辑,所以才会返回错误结果。
内容的提问来源于stack exchange,提问作者gggg2345
相关产品推荐
相关产品推荐

