You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何编写对比关联模型属性的Scope查询?

解决Laravel中Transaction模型的Crossed Scope问题

你原来的代码无法运行的核心原因是:Scope方法用于构建数据库查询语句,此时还没有具体的Transaction模型实例,不能直接通过$this访问关联模型的属性(比如$this->origin_account)——这些属性只有模型实例被加载后才能访问,而Scope需要在数据库层面完成字段比较。

下面提供两种可行的实现方式:

方法一:使用Join关联表直接比较字段

这种方式效率较高,直接通过SQL Join关联两个关联表,对比entity_id:

public function scopeCrossed($query)
{
    return $query->join('accounts', 'transactions.origin_account_id', '=', 'accounts.id')
                 ->join('concepts', 'transactions.concept_id', '=', 'concepts.id')
                 ->where('accounts.entity_id', '<>', 'concepts.entity_id')
                 ->select('transactions.*'); // 明确选择transactions表字段,避免关联表字段冲突
}

注意事项

  • 确保表名(accounts、concepts、transactions)与你的数据库实际表名一致;
  • 如果Transaction和Account的关联外键不是默认的origin_account_id,需调整Join语句中的外键字段。

方法二:使用Eloquent关联的子查询方式

若更倾向于用Eloquent关联语法而非原生Join,可结合whereHas和子查询实现:

public function scopeCrossed($query)
{
    return $query->whereHas('originAccount', function ($accountQuery) {
        $accountQuery->whereExists(function ($conceptQuery) {
            $conceptQuery->from('concepts')
                         ->whereColumn('concepts.id', 'transactions.concept_id')
                         ->whereColumn('concepts.entity_id', '<>', 'accounts.entity_id');
        });
    });
}

前提

需确保Transaction模型已定义正确的关联方法:

// Transaction模型中
public function originAccount()
{
    return $this->belongsTo(Account::class, 'origin_account_id');
}

public function concept()
{
    return $this->belongsTo(Concept::class);
}

内容的提问来源于stack exchange,提问作者E. Barney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:30:01