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

如何结合路由模型绑定在URL参数中使用可翻译字段?

解决Laravel多语言字段的路由模型绑定问题(无需显示ID)

核心思路

重写模型的resolveRouteBinding方法,让路由模型绑定能根据当前语言环境,查询JSON格式存储的多语言字段,无需额外添加slug字段或暴露ID。

步骤1:修改模型的路由绑定逻辑

针对Country和Province模型,分别添加以下代码:

Country模型

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;

class Country extends Model
{
    use HasTranslations;

    public $translatable = ['name'];

    // 重写路由绑定解析逻辑
    public function resolveRouteBinding($value, $field = null)
    {
        if ($field === 'name') {
            // 根据当前语言查询JSON字段中的对应值
            return $this->whereJsonContains("name->".app()->getLocale(), urldecode($value))->firstOrFail();
        }

        return parent::resolveRouteBinding($value, $field);
    }
}

Province模型

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;

class Province extends Model
{
    use HasTranslations;

    public $translatable = ['name'];

    // 重写路由绑定解析逻辑
    public function resolveRouteBinding($value, $field = null)
    {
        if ($field === 'name') {
            return $this->whereJsonContains("name->".app()->getLocale(), urldecode($value))->firstOrFail();
        }

        return parent::resolveRouteBinding($value, $field);
    }
}

步骤2:保留原路由写法

原有路由代码无需修改,继续使用自定义键的路由模型绑定:

Route::get('/{country:name}/{province:name}', [AdminController::class, 'locations']);

优化:抽成Trait避免重复代码

如果多个模型需要处理多语言路由绑定,可将逻辑抽成Trait减少重复代码:

namespace App\Traits;

trait TranslatableRouteBindingTrait
{
    public function resolveRouteBinding($value, $field = null)
    {
        // 检查字段是否属于多语言属性
        if (property_exists($this, 'translatable') && in_array($field, $this->translatable)) {
            return $this->whereJsonContains("{$field}->".app()->getLocale(), urldecode($value))->firstOrFail();
        }

        return parent::resolveRouteBinding($value, $field);
    }
}

之后在模型中直接使用该Trait即可:

class Country extends Model
{
    use HasTranslations, TranslatableRouteBindingTrait;

    public $translatable = ['name'];
}

补充说明

  • urldecode($value)用于处理URL中可能存在的编码字符(比如空格转成%20),确保查询匹配准确。
  • 该方案完全依赖已有的多语言JSON字段,无需修改数据库结构或添加额外逻辑。
  • 访问对应语言的URL时(例如/en/Canada/Ontario或/fr/Canada/Ontario),系统会自动根据当前语言环境查询匹配的模型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:03:17