🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### [](https://octobercms.com/docs/database/relations#inserting-related-models)插入相关模型 就像您[查询关系一样](https://octobercms.com/docs/database/relations#querying-relations),October支持使用方法或动态属性方法定义关系。例如,也许您需要`Comment`为`Post`模型插入一个新的。您可以直接从关系中插入,而不必在上手动设置`post_id`属性。`Comment``Comment` ### [](https://octobercms.com/docs/database/relations#inserting-method)通过关系方法插入 October提供了将新模型添加到关系的便捷方法。主要可以将模型添加到关系中或从关系中删除。在每种情况下,关系分别是关联的或分离的。 #### 添加方式 使用该`add`方法来关联新关系。 ~~~ $comment = new Comment(['message' => 'A new comment.']); $post = Post::find(1); $comment = $post->comments()->add($comment); ~~~ 注意,我们没有将`comments`关系作为动态属性来访问。相反,我们调用该`comments`方法来获取关系的实例。该`add`方法将自动`post_id`为新`Comment`模型添加适当的值。 如果需要保存多个相关模型,则可以使用以下`addMany`方法: ~~~ $post = Post::find(1); $post->comments()->addMany([ new Comment(['message' => 'A new comment.']), new Comment(['message' => 'Another comment.']), ]); ~~~ #### 删除方法 相比之下,该`remove`方法可用于取消关联,使其成为孤立记录。 ~~~ $post->comments()->remove($comment); ~~~ 对于多对多关系,该记录将从关系的集合中删除。 ~~~ $post->categories()->remove($category); ~~~ 如果是“属于”关系,则可以使用该`dissociate`方法,该方法不需要将相关模型传递给它。 ~~~ $post->author()->dissociate(); ~~~ #### 添加枢轴数据 当使用多对多关系时,该`add`方法将附加的中间“枢轴”表属性数组作为其第二个参数接受为数组。 ~~~ $user = User::find(1); $pivotData = ['expires' => $expires]; $user->roles()->add($role, $pivotData); ~~~ 该`add`方法的第二个参数还可以指定当作为字符串传递时,[延迟绑定](https://octobercms.com/docs/database/relations#deferred-binding)使用的会话密钥。在这些情况下,可以将数据透视表作为第三个参数提供。 ~~~ $user->roles()->add($role, $sessionKey, $pivotData); ~~~ #### 创建方法 虽然`add`并`addMany`接受一个完整的模型实例,你也可以使用该`create`方法,接受属性的PHP数组,创建了一个模型,并将其插入到数据库中。 ~~~ $post = Post::find(1); $comment = $post->comments()->create([ 'message' => 'A new comment.', ]); ~~~ 在使用该`create`方法之前,请确保查看有关属性[质量分配](https://octobercms.com/docs/database/model#mass-assignment)的文档,因为PHP数组中的属性受模型的“可填充”定义限制。 ### [](https://octobercms.com/docs/database/relations#inserting-dynamic-property)通过动态属性插入 关系可以通过访问它们的方式直接通过它们的属性来设置。使用这种方法设置关系将覆盖以前存在的任何关系。之后应像保存任何属性一样保存模型。 ~~~ $post->author = $author; $post->comments = [$comment1, $comment2]; $post->save(); ~~~ 或者,您可以使用主键设置关系,这在使用HTML表单时非常有用。 ~~~ // Assign to author with ID of 3 $post->author = 3; // Assign comments with IDs of 1, 2 and 3 $post->comments = [1, 2, 3]; $post->save(); ~~~ 通过将NULL值分配给属性,可以解除关联。 ~~~ $post->author = null; $post->comments = null; $post->save(); ~~~ 与[延迟绑定](https://octobercms.com/docs/database/relations#deferred-binding)类似,在不存在的模型上定义的关系会在内存中延迟,直到它们被保存为止。在此示例中,帖子尚不存在,因此`post_id`无法通过设置评论的属性`$post->comments`。因此,将关联推迟到通过调用`save`方法创建帖子之前。 ~~~ $comment = Comment::find(1); $post = new Post; $post->comments = [$comment]; $post->save(); ~~~ ### [](https://octobercms.com/docs/database/relations#inserting-many-to-many-relations)多对多关系 #### 装卸 在使用多对多关系时,模型提供了一些其他的辅助方法,使使用相关模型更加方便。例如,让我们假设一个用户可以有许多角色,而一个角色可以有许多用户。要通过在连接模型的中间表中插入一条记录来将角色附加给用户,请使用以下`attach`方法: ~~~ $user = User::find(1); $user->roles()->attach($roleId); ~~~ 将关系附加到模型时,您还可以传递要插入到中间表中的其他数据数组: ~~~ $user->roles()->attach($roleId, ['expires' => $expires]); ~~~ 当然,有时可能有必要从用户中删除角色。若要删除多对多关系记录,请使用`detach`方法。该`detach`方法将从中间表中删除适当的记录;但是,两个模型都将保留在数据库中: ~~~ // Detach a single role from the user... $user->roles()->detach($roleId); // Detach all roles from the user... $user->roles()->detach(); ~~~ 为了方便起见,`attach`并且`detach`还接受ID作为输入的数组: ~~~ $user = User::find(1); $user->roles()->detach([1, 2, 3]); $user->roles()->attach([1 => ['expires' => $expires], 2, 3]); ~~~ #### 同步方便 您也可以使用该`sync`方法构造多对多关联。该`sync`方法接受ID数组以放置在中间表上。给定数组中没有的任何ID将从中间表中删除。因此,完成此操作后,中间表中将仅存在数组中的ID: ~~~ $user->roles()->sync([1, 2, 3]); ~~~ 您还可以传递带有ID的其他中间表值: ~~~ $user->roles()->sync([1 => ['expires' => true], 2, 3]); ~~~ ### [](https://octobercms.com/docs/database/relations#touching-parent-timestamps)感动的父母时间戳 当一个模型`belongsTo`或`belongsToMany`另一个模型(例如`Comment`属于a)时`Post`,在更新子模型时更新父时间戳有时会很有帮助。例如,当`Comment`模型更新时,您可能想要自动“触摸”`updated_at`所有者的时间戳`Post`。只需`touches`向子模型添加一个包含关系名称的属性: ~~~ class Comment extends Model { /** * All of the relationships to be touched. */ protected $touches = ['post']; /** * Relations */ public $belongsTo = [ 'post' => ['Acme\Blog\Models\Post'] ]; } ~~~ 现在,当您更新时`Comment`,所有者`Post`将同时`updated_at`更新其列: ~~~ $comment = Comment::find(1); $comment->text = 'Edit to this comment!'; $comment->save(); ~~~