Laravel 获取构建器而不是关系
Posted
技术标签:
【中文标题】Laravel 获取构建器而不是关系【英文标题】:Laravel getting builder instead of relation 【发布时间】:2016-01-31 07:11:34 【问题描述】:我正在尝试在保存模型之前对其进行验证。显然,如果模型无效,则不应将其保存到数据库中。当验证失败时,它会抛出异常并且不会继续保存。下面的工作:
$question = new Question([...]);
$question->validate();
$question->save();
我对 answers()
hasMany 关系有疑问。根据this answer,我应该可以在关系对象上调用add()
:
$question = new Question([...]);
$question->answers()->add(new Answer([...]));
$question->validate();
$question->save();
以上失败:
Call to undefined method Illuminate\Database\Query\Builder::add()
我认为 answers() 函数会返回一个 HasMany 关系对象,但看起来我正在获得一个构建器。为什么?
【问题讨论】:
如果 answers 是一个关系,你会想要调用 $question->answers 而不是 $question->answers() (不要调用函数)。确保使用定义关系的函数的名称,而不是模型名称本身(如果它们相同就可以)。 【参考方案1】:answers()
确实返回了一个 HasMany 对象。但是,由于 HasMany
对象上没有 add
方法,Laravel 求助于 php 的 __call
魔术方法。
public function __call($method, $parameters)
$result = call_user_func_array([$this->query, $method], $parameters);
if ($result === $this->query)
return $this;
return $result;
__call
方法获取查询实例并尝试对其调用add
方法。但是,查询生成器上没有 add
方法,这就是您收到该消息的原因。
最后,add
方法是 Laravel 的 Eloquent Collection 的一部分,而不是 HasMany 的一部分。为了获得 Collection 类,您需要删除括号(如链接中提供的答案所示)并改为这样做:
$question->answers->add(new Answer([...]));
【讨论】:
谢谢!我错过了不带括号的部分。 将答案添加到集合中不会在保存问题时将其保存到数据库中。【参考方案2】:没有add
方法。使用save
方法:
$question->answers()->save(new Answer([]));
【讨论】:
在执行验证之前我无法将对象保存到数据库中,因此我无法在集合上销售 save()。以上是关于Laravel 获取构建器而不是关系的主要内容,如果未能解决你的问题,请参考以下文章