【问题标题】:Eloquent relations - attach (but don't save) to Has Many雄辩的关系 - 附加(但不保存)到 Has Many
【发布时间】:2014-07-20 00:20:40
【问题描述】:

我建立了以下关系:

class Page {
    public function comments() {
        return $this->hasMany('Comment');
    }
}

class Comment {
    public function page() {
        return $this->belongsTo('Page');
    }
}

非常标准。一页可以有多个cmet,一条评论属于一页。

我希望能够创建一个新页面:

$page = new Page;

还有评论

$comment = new Comment;

并将评论附加到页面,不保存任何内容

$page->comments->associate($comment);

我尝试了以下方法:

// These are for one-to-many from the MANY side (eg. $comment->page->associate...)
$page->comments->associate($comment);   // Call to undefined method Illuminate\Database\Eloquent\Collection::associate()
$page->comments()->associate($comment); // Call to undefined method Illuminate\Database\Query\Builder::associate()

// These 2 are for many-to-many relations, so don't work
$page->comments->attach($comment);      // Call to undefined method Illuminate\Database\Eloquent\Collection::attach()
$page->comments()->attach($comment);    // Call to undefined method Illuminate\Database\Query\Builder::attach()

// These 2 will (if successful) save to the DB, which I don't want
$page->comments->save($comment);        // Call to undefined method Illuminate\Database\Eloquent\Collection::save()
$page->comments()->save($comment);      // Integrity constraint violation: 1048 Column 'page_id' cannot be null

真正奇怪的是,做相反的事情(将页面附加到评论)可以正常工作:

$comment->page()->associate($page);

相关文档是here,但他们没有提到附加到一对多的一侧。甚至可能吗? (我觉得应该是)

【问题讨论】:

    标签: laravel laravel-4 eloquent relationship


    【解决方案1】:

    据 Benubird 所说,我只是想补充一些东西,因为我今天偶然发现了这个:

    您可以像 Benubird 所说的那样在集合上调用 add 方法。 为了考虑 edpaaz(附加触发查询)的问题,我这样做了:

    $collection = $page->comments()->getEager(); // Will return the eager collection
    $collection->add($comment) // Add comment to collection
    

    据我所知,这将阻止额外的查询,因为我们只使用关系对象。

    在我的情况下,其中一个实体是持久的,而第一个(在您的案例页面中)不是(并且要创建)。由于我必须处理一些事情并希望以对象方式处理它,因此我想将持久实体对象添加到非持久实体对象中。不过,也应该适用于非持久性。

    感谢 Benubird 为我指明了正确的方向。希望我的补充对我有帮助。

    请记住,这是我在 stackoverflow 上的第一篇文章,所以请留下您的反馈意见。

    【讨论】:

      【解决方案2】:

      听起来您只是想将新的评论对象添加到页面的 cmets 集合中 - 您可以使用基本的集合添加方法轻松地做到这一点:

      $page = new Page;
      $comment = new Comment;
      $page->comments->add($comment);
      

      【讨论】:

      • 完美,正是我需要的:) 谢谢
      • 之后如何保存cmets?
      • @Boedy 这是一个单独的问题 - 这只是在谈论未链接到数据库的对象。如果要保存评论,则需要先保存页面,然后使用 >save() 方法链接它们。我所做的实际上不会将它们连接到数据库中,因为它们没有 ID;它只是将评论对象添加到集合中。
      • 在这里说明显而易见的......您应该记住,在$page 中调用comments 属性将触发数据库中的查询,因此它可能比您要慢期待..
      • 你应该也可以使用 $page->push() 来保存页面和所有相关的 cmets,而不是单独保存一个。
      【解决方案3】:

      您不能这样做,因为没有要链接的 ID。

      所以首先你需要保存父模型 ($page) 然后保存子模型:

      // $page is existing model, $comment don't need to be
      $page->comments()->save($comment); // saves the comment
      

      或者反过来,这次不保存:

      // again $page exists, $comment don't need to
      $comment->page()->associate($page); // doesn't save the comment yet
      $comment->save();
      

      【讨论】:

      • 这是有道理的,但如果我这样做$comment->page()->associate($page),那么它会正确附加它,尽管页面也没有 ID
      • 不,它不会抛出任何错误,但它也没有正确关联它。事实上,它将page_id 设置为null,因为正如您所说,$page 对象上没有 id。
      • 不,它关联正确。 page_id 确实为空,但关系数组已填充 - dd($comment) 打印:grab.by/xksA
      • 如果它失败了,我不会称之为正确的。实际上应该存在某种错误,但 Eloquent 在这种情况下没有提供任何错误。
      • 它不会失败 :) 页面的 ID 是 null,因此它将 $background->page_id 设置为 null。然后它将Page 添加到关系中。这一切都是有道理的,是正确的,没有失败
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多