【问题标题】:Overriding a Laravel Eloquent Model in an accessor returns 0 on using a property在访问器中覆盖 Laravel Eloquent 模型在使用属性时返回 0
【发布时间】:2018-09-19 12:14:46
【问题描述】:

抱歉(也许)有些不清楚的问题。我不知道如何以其他方式表达它。 (欢迎提出建议:p)但是我认为代码不言自明:

我正在使用访问器来获取页面的主题(如果没有主题集,则从其父级获取):

public function getThemeAttribute()
{
    if(!isset($this->theme_uid) || $this->theme_uid === null || $this->theme_uid === '')
    {
        return $this->parent->theme()->first();
    }

    //return $this->theme->first();
    return self::theme()->first();
}

如果我请求主题属性本身,这确实有效,例如:

$page->theme

返回:

Theme {#741 ▼ ...etcetera

但如果我尝试访问返回模型的属性,例如:

$page->theme->uid

我明白了:

0

可能与幕后发生的事情有关,但还没有弄清楚,所以任何帮助都会很棒。

已经谢谢了!

问候吉斯

【问题讨论】:

  • 如果我正确理解了您的代码,它应该以循环结束,因为您使用的是 getThemeAttribute 但也在同一个函数中使用 $this->theme,它们都引用了同一个函数。
  • @Gijs Beijer 我发布了一些想法。另外,为什么你会得到0 的uuid,你能做这个测试吗? dd($theme->getAttributes());
  • 我 @milo526 你在哪里复制了试用代码,我实际上使用 self::theme() 来克服这个问题,它确实返回了正确的主题模型实例,但我不能调用任何属性。跨度>
  • @Andrius Rimkus,致电:->getAttributes() 确实向我展示了价值观
  • 如果您在原始属性数组中看到uuid,那么问题可能与uuid 访问器有关。

标签: php laravel inheritance eloquent accessor


【解决方案1】:

好的,作为一个小的代码改进:

(!isset($this->theme_uid) || $this->theme_uid === null) === !isset($this->theme_uid)

isset — 确定变量是否已设置且不为 NULL

现在这部分:

return $this->theme->first();

会导致魔术方法__get递归并抛出异常。 https://bugs.php.net/bug.php?id=71254

在您的情况下,theme 是一种关系,而不是一种属性。我认为attribute 访问器应该用于它们的预期目的-attribute 访问突变。您可以通过自定义关系表达您的情况:

public function availableTheme()
{
    if(!empty($this->theme_uid))
    {
        return $this->theme();
    }

    return $this->parent->theme();
}

// $page->availableTheme
// $page->avalaibleTheme()->where(...)->first()

【讨论】:

  • 嗨,您的 availableTheme() 方法确实有效,但它让我在视图中留下了一种难看的语法,我真的希望它对团队的其他成员来说是直观的。我将使用我现在使用的方法编辑我的问题(合并->getAttributes() @Andrius Rimkus 建议
  • 命名由你决定。只是想解决我心中的问题 - 为关系设置访问器。
【解决方案2】:

好的,所以我采用的方法如下:

public function getThemeAttribute()
{
    if(!isset($this->theme_uid) || $this->theme_uid === null || $this->theme_uid === '')
    {
        return (object)$this->parent->theme()->first()->getAttributes();
    }

    return (object)self::theme()->first()->getAttributes();
}

这允许我在需要访问值的地方有一个很好的语法(例如:$page->theme->uid$page->theme->color,而不必担心它是在父级上还是在哪种类型上(Relation、@987654325 @等)在主题上的返回值是。

如果有人能告诉我为什么这不能直接实现,我仍然很感兴趣,任何在这里提供帮助的人:谢谢!

【讨论】:

    猜你喜欢
    • 2019-05-12
    • 1970-01-01
    • 2018-01-13
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 2021-07-26
    • 2014-06-17
    相关资源
    最近更新 更多