【问题标题】:Laravel - calling model's method throws undefined method Illuminate\Database\Query\BuilderLaravel - 调用模型的方法会抛出未定义的方法 Illuminate\Database\Query\Builder
【发布时间】:2017-05-22 04:20:27
【问题描述】:

模型的参数方法有问题。我有 2 个 PageContentTranslation。我想根据语言得到ContentTranslation,所以我在Page模型中有以下方法:

public function contentTranslations($language) {
    return $this->hasMany('App\ContentTranslation')->where('language', $language);
}

然后我在PageController 中有一个方法可以根据语言获取页面:

public function getPagesByLanguage($language)
{
    $pages = Page::orderBy('position', 'asc')->get();
    foreach ($pages as $page) {
        $page->contentTranslations($language);
    }
    $return $pages;
}

我以 JSON 格式返回我的结果(我使用 Laravel 作为 api)。但是这种方法行不通。它向我抛出错误:

调用未定义的方法 Illuminate\Database\Query\Builder::contentTranslations()

前段时间,我想为所有语言返回contentTranslations,所以我在contentTranslations 模型方法中没有参数,在foreach 循环中调用$page->contentTranslations; 后一切正常。为什么我在将参数传递给方法时遇到了麻烦?

【问题讨论】:

    标签: php laravel eloquent laravel-eloquent


    【解决方案1】:

    你应该使用eager loading to avoid N+1 query problem:

    public function getPagesByLanguage($language)
    {
        return Page::with(['contentTranslations' => function($q) use ($language) {
                        $q->where('language', $language);
                   }])
                   ->orderBy('position', 'asc')
                   ->get();
    }
    

    同时改变你的关系:

    public function contentTranslations() {
        return $this->hasMany('App\ContentTranslation');
    }
    

    【讨论】:

    • 太好了,它按我的预期工作......但是如果我现在只想从contentTranslations 中选择一些列怎么办?我试图在$q->where... 语句之后添加->select(array('slug', 'language'),但随后它在 content_translations 数组中返回 0 个项目。你也可以帮我解决这个问题吗? :)
    • 您可以这样做$q->where('language', $language)->select(['page_id', 'slug', 'language']; 请注意,您始终必须添加外键才能使关系正常工作。
    猜你喜欢
    • 2018-10-03
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 2014-04-25
    • 2017-02-20
    • 2017-10-04
    • 2018-05-17
    相关资源
    最近更新 更多