Laravel 5 M2M多态关系未设置


Laravel 5 M2M Polymorphic relations not setting?

以下是基本代码:

/**
 * Post.php
 */
class Post extends Illuminate'Database'Eloquent'Model {
    public function tags() {
        return $this->morphToMany('Tag', 'taggable', 'taggable_taggables')
            ->withTimestamps();
    }
}
/**
 * Tag.php
 */
class Tag extends Illuminate'Database'Eloquent'Model {
    protected $table = 'taggable_tags';
    public function taggable() {
        return $this->morphTo();
    }
}

现在取以下代码:

// assume that both of these work (i.e. the models exist)
$post = Post::find(1);
$tag = Tag::find(1);
$post->tags()->attach($tag);

到目前为止还不错。正在taggable_taggables数据透视表中创建关系。然而,如果我立即这样做:

dd($post->tags);

它返回一个空集合。attach()似乎在数据库中创建了关系,但在模型的当前实例中没有。

这可以通过再次加载模型进行检查:

$post = Post::find(1);
dd($post->tags);

现在,这种关系得到了补充。

我确信这在Laravel 4.2中起到了作用——即关系在attach()之后立即更新。有没有什么可以促使拉拉威尔5做同样的事情?

Laravel只会加载一次relationship属性,无论是急切加载还是懒惰加载。这意味着,一旦加载了属性,除非显式地重新加载了关系,否则对关系的任何更改都不会反映在属性中。

你发布的确切代码应该如预期的那样工作,所以我假设有一部分缺失了。例如:

$post = Post::find(1);
$tag = Tag::find(1);
$post->tags()->attach($tag);
// This should dump the correct data, as this is the first time the
// attribute is being accessed, so it will be lazy loaded right here.
dd($post->tags);

对比:

$post = Post::find(1);
$tag = Tag::find(1);
// access tags attribute here which will lazy load it
var_dump($post->tags);
$post->tags()->attach($tag);
// This will not reflect the change from attach, as the attribute
// was already loaded, and it has not been explicitly reloaded
dd($post->tags);

为了解决这个问题,如果需要刷新关系属性,可以使用load()方法,而不是重新检索父对象:

$post = Post::find(1);
$tag = Tag::find(1);
// access tags attribute here which will lazy load it
var_dump($post->tags);
$post->tags()->attach($tag);
// refresh the tags relationship attribute
$post->load('tags');
// This will dump the correct data as the attribute has been
// explicitly reloaded.
dd($post->tags);

据我所知,没有任何参数或设置可以强制Laravel自动刷新关系。我也想不出可以挂接的模型事件,因为您实际上并没有更新父模型。我能想到的主要有三种选择:

  1. 在模型上创建一个方法,用于执行附着和重新加载。

    public function attachTags($tags) {
        $this->tags()->attach($tags);
        $this->load('tags');
    }
    $post = Post::find(1);
    $tag = Tag::find(1);
    $post->attachTags($tag);
    dd($post->tags);
    
  2. 创建一个新的关系类来扩展BelongsToMany关系类,并重写attach方法来执行所需的逻辑。然后,创建一个扩展Eloquent model类的新模型类,并重写belongsToMany方法来创建新关系类的实例。最后,更新Post模型以扩展新的model类,而不是Eloquent model类。

  3. 只要确保在需要的时候总是重新加载你的关系。