【问题标题】:Eloquent model hasOne returning a non related modelEloquent 模型 hasOne 返回一个不相关的模型
【发布时间】:2022-01-05 07:00:15
【问题描述】:

背景资料

在我的项目中,我使用的是 Illuminate\Database 包。

我设置了两个类:User 和 Customtag。我正在尝试在两者之间建立关系。

我有两个表:vip_users 和 vip_customtags。两者都有一个名为“steamid”的列,即 VARCHAR(255)。

现在,有多个用户,但对于这种情况:我有一个用户的 steamid 为 76561198048535340。

还有一个带有steamid 7656119804853534的customtag1

问题

foreach (User::all() as $u)
{
    echo "User: " . $u->vip_id . "<br>";
    print_r($u->customtag);
}

此代码打印用户 1、2、3、4、5... 等。但是当蒸汽 ID 为 76561198048535340 的用户出现时,它返回蒸汽 ID 为 7656119804853534 的自定义标签1

User: 1
User: 2
VipSystem\Models\Customtag Object
(
...
    [attributes:protected] => Array
        (
            [steamid] => 76561198048535341
        )

    [original:protected] => Array
        (
            [steamid] => 76561198048535341

        )
...
)
User: 3
User: 4
User: 5

反过来,请求所有自定义标签可以正常工作。例如:

foreach (Customtag::all() as $tag)
{
    echo "Tag: " . $tag->id . "<br>";
    print_r($tag->user);
}

打印:

Tag: 1
Tag: 2
Tag: 3
Tag: 4
Tag: 5

用户

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;

class User extends Model
{
    public $timestamps = false;
    public $primaryKey = "steamid";

    public function customtag(): HasOne
    {
        return $this->hasOne(Customtag::class, "steamid", "steamid");
    }
}

自定义标签

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Customtag extends Model
{

    public $timestamps = false;
    public $primaryKey = "id";

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, "steamid", "steamid");
    }
}

【问题讨论】:

    标签: php laravel eloquent


    【解决方案1】:

    默认情况下,Laravel 类期望主键是一个递增的整数。你需要告诉班级主键实际上是一个字符串。

    将以下内容添加到您的 User 类中:

    protected $keyType = 'string';
    public $incrementing = false;
    

    【讨论】:

      【解决方案2】:
      /**
       * @return Customtag
       *
       * @throws ModelNotFoundException
       */
      public function customtag()
      {
          return Customtag::where('steamid', '=', '' . $this->steamid)->get()->firstOrFail();
      }
      

      将 steamid 强制为字符串似乎对我有用。使用整数执行 SQL。

      【讨论】:

      • 将我的数据库更改为使用 bigint 而不是 varchar。它现在可以与 hasOne 和 belongsTo 完美搭配。
      • collections 没有firstOrFail 方法......不要认为你打算在那里调用get......你也会为此使用关系而不是这样做询问自己(通常)
      猜你喜欢
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 2016-02-29
      • 1970-01-01
      • 1970-01-01
      • 2023-02-16
      • 1970-01-01
      相关资源
      最近更新 更多