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

Laravel使用hasOne()出现‘Using $this when not in object context’错误

问题解决:Laravel模型关联报错及分类名称获取方案

错误原因分析

出现Using $this when not in object context错误,大概率是以下两种情况:

  • 把关联方法定义成了静态方法(加了static关键字),导致无法在静态上下文中使用$this
  • 调用关联时用了静态调用(比如AdminContent::category()),而非通过模型实例调用

正确的模型关联配置

首先明确关联逻辑:AdminContent的content_category_id关联AdminCategory的ctgry_id,属于从属关系,所以应该用belongsTo(而非hasOne,hasOne是反向主从关系,逻辑上不匹配)。

AdminContent 模型代码

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class AdminContent extends Model
{
    protected $table = 'admin_contents'; // 指定表名(若模型名与表名不符合默认规则)

    // 定义与分类的关联
    public function category()
    {
        // 参数:关联模型、当前模型外键字段、关联模型主键字段
        return $this->belongsTo(AdminCategory::class, 'content_category_id', 'ctgry_id');
    }
}

AdminCategory 模型代码

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class AdminCategory extends Model
{
    protected $table = 'admin_categories';
    protected $primaryKey = 'ctgry_id'; // 必须指定自定义主键,否则Laravel会默认查找`id`字段
}

获取分类名称的方法

1. 单个内容实例获取分类名

// 获取单个内容
$content = AdminContent::find(1);
// 直接通过关联属性获取分类名称
$categoryName = $content->category->category_name;

2. 批量查询时预加载关联(避免N+1查询问题)

// 预加载category关联,一次性查询所有内容及其分类
$contents = AdminContent::with('category')->get();

foreach ($contents as $content) {
    // 处理可能存在的无关联分类情况,避免报错
    $categoryName = optional($content->category)->category_name;
    echo $categoryName;
}

补充说明

如果坚持要用hasOne(不推荐,逻辑不符),写法如下,仅适用于特殊场景:

public function category()
{
    return $this->hasOne(AdminCategory::class, 'ctgry_id', 'content_category_id');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:05:16