shortcodes/model-relationship

这是一个通过观察者自动处理模型关系的包,简化了模型关系的管理

3.0.17 2020-05-11 13:49 UTC

README

这是一个通过特性自动处理模型关系的包

用法

你所需要做的就是使用 Relationship 特性到你的模型。注意,当你使用特性时,启动的观察者会处理所有关系

记得在你的所有关系方法之上添加 @relation 注解

它如何工作

当创建或更新操作被触发时,特性方法会自动在提供的属性中查找关系,并按关系类型管理它们

处理的关系类型

  • HasOne
  • BelongsTo
  • HasMany
  • BelongsToMany

先决条件

假设我们有一个具有关系的示例 Article 模型

class Articel extends Model{

        /**
         * @relation
         */
        public function author()
        {
            return $this->belongsTo(Author::class);
        }
    
        /**
         * @relation
         */
        public function referrals()
        {
            return $this->hasMany(Referral::class);
        }
    
        /**
         * @relation
         */
        public function image()
        {
            return $this->hasOne(Image::class);
        }
    
        /**
         * @relation
         */
        public function tags()
        {
            return $this->belongsToMany(Tag::class);
        }

}

HasOne

在添加 HasOne 关系时,有几种方法可以做到

提供 image_id

Article::create([...$someArticleAttributes,'image_id'=>$image_id]);

提供带有 ID 的 image 对象(忽略 image 的所有其他属性)

Article::create([...$someArticleAttributes,'image'=> ['id'=>$image_id]]);

提供没有 ID 的 image 对象(将创建一个图像并将其绑定到文章)

Article::create([...$someArticleAttributes,'image'=> ['url'=>'https://example.url','title'=>'Example title']]);

BelongsTo

在添加 BelongsTo 关系时,可以提供 object_id 或对象表示法 object['id']

提供 author_id

Article::create([...$someArticleAttributes,'author_id'=>$author_id]);

提供带有 ID 的 author 对象(忽略 author 的所有其他属性)

Article::create([...$someArticleAttributes,'author'=> ['id'=>$author_id]]);

HasMany

在添加 HasMany 关系时,应提供相关对象的集合

Article::create([...$someArticleAttributes,'referrals'=> [
    [
        'url'=>'https://example.url'
    ],
    [
        'url'=>'https://example.url'
    ],
    [
        'url'=>'https://example.url'
    ]
]);

在更新 Article 中的 HasMany 关系时,应提供类似的相关对象集合

$article->update(['referrals'=> [
    [
        'id'=>1,
        'url'=>'https://example.url'
    ],
    [
        'id'=>2,
        'url'=>'https://example.url'
    ],
    [
        'url'=>'https://example.url'
    ]
]);

如果相关模型属性包含 id,则将其更新。如果没有 - 它将创建并绑定。

重要!在上述所有引用中,不在引用属性数组中的引用将被删除。

向关系添加新对象。

如果您不想将所有现有的引用 ID 传递到引用数组中(因此它们不会被删除),则可以使用后缀表示法

$article->update(['referrals_add'=> [
    [
        'url'=>'https://example.url'
    ]
]);

与文章关联的旧引用将不受影响。

请注意,如果您向 referrals_add 数组提供已存在的模型(带有 ID),则它将被附加,如下所述。

从关系中移除新对象。

如果您只想删除一个或多个引用而无需将 ID 传递到引用数组中(因此它们不会被删除),则可以使用另一种后缀表示法

$article->update(['referrals_delete'=> [
    [
        'id'=>1
    ]
]);

与文章关联的旧引用将不受影响。

将已存在的对象附加到关系中。

如果您想将现有的模型(如 referrals)关联到没有分配关系 ID(null)的模型,则可以使用后缀表示法 _attach

$article->update(['referrals_attach'=> [
    [
        'id'=>1
    ]
]);

现有的引用将与文章关联。

从关系中删除对象。

如果您想取消关联现有的模型(如 referrals)并将外键设置为 null,则可以使用后缀表示法 _detach

$article->update(['referrals_detach'=> [
    [
        'id'=>1
    ]
]);

在 referrals_detach 数组中提供的 ID 将从文章中取消关联。

请记住,此功能需要将关系的数据库外键设置为可空。

请记住,即使相关对象与另一个模型关联,也会执行关联。

排序关系对象

有时您需要按positionhasMany关系进行排序。在这种情况下,您只需简单地传递一个包含所需顺序的ID的引用数组即可。如果相关对象(在本例中为引用)必须包含数据库中的position列,则可以实现此功能。

$article->update(['referrals'=> [
    [
        'id'=>5
    ],
    [
        'id'=>3
    ],
    [
        'id'=>2
    ],
]);

请记住,缺失的ID将被删除

BelongsToMany

在添加BelongsToMany关系时,您应提供相关对象ID的集合

 Article::create([...$someArticleAttributes,'tags'=> [
        [
            'id'=>5
        ],
        [
            'id'=>3
        ],
        [
            'id'=>2
        ],
        [
            'id'=>1
        ],
    ]);

上述标签将通过多对多关系与文章相关联。

如果您想向关联表传递额外的数据,只需将其添加到属性表中即可

 Article::create([...$someArticleAttributes,'tags'=> [
        [
            'id'=>5,
            'weight'=>1
        ],
        [
            'id'=>3,
            'weight'=>1
        ],
        [
            'id'=>2,
            'weight'=>3
        ],
        [
            'id'=>1,
            'weight'=>4
        ],
    ]);

由于Laravel的belongsToMany关系使用force选项填充关联表,请记住不要传递不在数据库中的任何字段

向关系添加新对象。

您还可以使用类似于hasMany关系后缀的_attach后缀添加一个或多个对象到belongsToMany关系

$article->update(['tags_attach'=> [
    [
        'id'=>1
    ],
    [
        'id'=>2
    ]
]);

与文章相关联的数组中缺失的所有标签都不会受到影响。

从关系中移除新对象。

当您想要移除关联时,_detach前缀的工作方式与此类似

$article->update(['tags_detach'=> [
    [
        'id'=>1
    ],
    [
        'id'=>2
    ]
]);

与文章相关联的数组中缺失的所有标签都不会受到影响。

排序关系对象

类似于hasMany,有时您需要按positionbelongsToMany相关关系进行排序。在这种情况下,您只需简单地传递一个包含所需顺序的ID的tags数组即可。如果关联表中存在position列,则可以实现此功能。

$article->update(['tags'=> [
    [
        'id'=>5
    ],
    [
        'id'=>3
    ],
    [
        'id'=>2
    ],
]);

请记住,缺失的ID将被删除

该软件包仍在建设中