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

Laravel多态关联查询:按taggable_id和taggable_type筛选user_tag_id

问题:筛选指定taggable_type和taggable_id的user_tag_id

我需要筛选出所有符合指定taggable_type和taggable_id的user_tag_id,本人对查询语句不熟悉,且刚接触Laravel仍在学习中。

目前尝试的代码

$check = Tag::whereIn('user_tag_id', function ( $query ) {
            $query->select('taggable_id')->from('tags')->groupBy('user_tag_id');
        })->get();
        return $check;

返回结果

"id" => 1
        "user_tag_id" => 1
        "taggable_type" => "App\Domains\TradeSetup\Models\TradeSetup"
        "taggable_id" => 1
        "type" => null
        "state" => null
        "created_at" => "2022-11-25 01:57:42"
        "updated_at" => "2022-11-25 01:57:42"
        "deleted_at" => null

"id" => 6
        "user_tag_id" => 1
        "taggable_type" => "App\Domains\Trade\Models\Trade"
        "taggable_id" => 1
        "type" => null
        "state" => null
        "created_at" => "2022-11-25 02:31:24"
        "updated_at" => "2022-11-25 02:31:24"
        "deleted_at" => null

相关模型定义

TradeSetup模型

public function userTag()
{
    return $this->hasMany(UserTag::class);
}

public function tags()
{
    return $this->morphMany(Tag::class, 'taggable');
}

Tag模型

public function taggable()
{
    return $this->morphTo();
}

public function userTag()
{
    return $this->belongsTo(UserTag::class);
}

期望目标

我期望的SQL语句大致如下:

SELECT USER_TAG_ID
FROM TAGS
WHERE TAGGABLE_ID = 1 AND TAGGABLE_TYPE = 'App\Domains\TradeSetup\Models\TradeSetup'

即仅返回符合taggable_id=1且taggable_type=TradeSetup条件的user_tag_id相关记录。


解决方案

直接查询Tag模型就能实现需求,不需要复杂的子查询,这里提供两种简单的写法:

方法一:直接条件查询

// 直接筛选条件,获取user_tag_id列表
$userTagIds = Tag::where('taggable_id', 1)
    ->where('taggable_type', 'App\Domains\TradeSetup\Models\TradeSetup')
    ->pluck('user_tag_id'); // 只提取user_tag_id字段,返回集合

// 如果需要去重(避免重复的user_tag_id),加上distinct()
$userTagIds = Tag::where('taggable_id', 1)
    ->where('taggable_type', 'App\Domains\TradeSetup\Models\TradeSetup')
    ->distinct()
    ->pluck('user_tag_id');

方法二:通过TradeSetup模型关联查询

既然TradeSetup模型已定义tags关联,也可以先找到指定实例,再通过关联获取对应的user_tag_id:

$tradeSetup = TradeSetup::find(1);
$userTagIds = $tradeSetup->tags()->pluck('user_tag_id');

// 同样可以加distinct去重
$userTagIds = $tradeSetup->tags()->distinct()->pluck('user_tag_id');

关键说明

  • pluck('user_tag_id')直接返回仅包含目标字段值的集合,比get()返回完整模型实例更贴合需求;
  • 若数据库存在同一user_tag_id对应多条符合条件的记录,distinct()可确保结果无重复;
  • taggable_type必须使用完整模型类名(与数据库存储值一致),不能简写为TRADESETUP。

内容的提问来源于stack exchange,提问作者harith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:05:29