🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 关联操作 ### 介绍 数据库表通常相互关联。例如,博客文章可能有很多评论,或者订单可能与放置它的用户有关。October使管理和使用这些关系变得容易,并支持几种不同类型的关系。 > **注:**如果您在查询中选择特定的列和要加载的关系为好,你需要确保做出包含密钥数据(即列`id`,`foreign_key`等等)都包含在你的SELECT语句。否则,十月无法建立联系。 ### [](https://octobercms.com/docs/database/relations#relationship-types)关系类型 可以使用以下关系类型: * [一对一](https://octobercms.com/docs/database/relations#one-to-one) * [一对多](https://octobercms.com/docs/database/relations#one-to-many) * [多对多](https://octobercms.com/docs/database/relations#many-to-many) * [有很多通过](https://octobercms.com/docs/database/relations#has-many-through) * [多态关系](https://octobercms.com/docs/database/relations#polymorphic-relations) * [多对多态关系](https://octobercms.com/docs/database/relations#many-to-many-polymorphic-relations) ### [](https://octobercms.com/docs/database/relations#deferred-binding)延迟绑定 延迟绑定允许您推迟模型关系的绑定,直到主记录提交更改为止。如果您需要准备一些模型(例如文件上传)并将它们与尚不存在的其他模型相关联,则这特别有用。 您可以使用**会话密钥将**任何数量的**从属**模型相对于**主**模型进行延迟。当主记录与会话密钥一起保存时,与从属记录的关系将自动为您更新。后端[Form行为](https://octobercms.com/docs/backend/form)自动支持延迟绑定,但是您可能希望在其他地方使用此功能。[](https://octobercms.com/docs/backend/form) ### [](https://octobercms.com/docs/database/relations#deferred-session-key)生成会话密钥 会话密钥对于延迟绑定是必需的。您可以将会话密钥视为事务标识符。相同的会话密钥应用于绑定/解除绑定关系并保存主模型。您可以使用PHP`uniqid()`函数生成会话密钥。请注意,[表单帮助程序](https://octobercms.com/docs/cms/markup#forms)会自动生成一个包含会话密钥的隐藏字段。 ~~~ $sessionKey = uniqid('session_key', true); ~~~ ### [](https://octobercms.com/docs/database/relations#defer-binding)推迟关系绑定 除非保存该帖子,否则下一个示例中的评论将不会添加到该帖子中。 ~~~ $comment = new Comment; $comment->content = "Hello world!"; $comment->save(); $post = new Post; $post->comments()->add($comment, $sessionKey); ~~~ > **注意**:该`$post`对象尚未保存,但是如果保存发生关系将被创建。 ### [](https://octobercms.com/docs/database/relations#defer-unbinding)推迟解除关系 除非保存该帖子,否则下一个示例中的评论将不会被删除。 ~~~ $comment = Comment::find(1); $post = Post::find(1); $post->comments()->remove($comment, $sessionKey); ~~~ ### [](https://octobercms.com/docs/database/relations#list-all-bindings)列出所有绑定 使用`withDeferred`关系的方法加载所有记录,包括延迟的。结果还将包括现有关系。 ~~~ $post->comments()->withDeferred($sessionKey)->get(); ~~~ ### [](https://octobercms.com/docs/database/relations#cancel-all-bindings)取消所有绑定 取消延迟绑定并删除从属对象而不是将它们保留为孤立对象是个好主意。 ~~~ $post->cancelDeferred($sessionKey); ~~~ ### [](https://octobercms.com/docs/database/relations#commit-all-bindings)提交所有绑定 保存主模型时,可以通过为会话密钥提供方法的第二个参数来提交(绑定或取消绑定)所有延迟的绑定`save`。 ~~~ $post = new Post; $post->title = "First blog post"; $post->save(null, $sessionKey); ~~~ 相同的方法适用于模型的`create`方法: ~~~ $post = Post::create(['title' => 'First blog post'], $sessionKey); ~~~ ### [](https://octobercms.com/docs/database/relations#lazily-commit-bindings)延迟提交绑定 如果`$sessionKey`在保存时无法提供,则可以使用以下代码随时提交绑定: ~~~ $post->commitDeferred($sessionKey); ~~~ ### [](https://octobercms.com/docs/database/relations#cleanup-bindings)清理孤立的绑定 销毁所有尚未提交且早于1天的绑定: ~~~ October\Rain\Database\Models\DeferredBinding::cleanUp(1); ~~~ > **注意:**十月会自动销毁早于5天的延迟绑定。后端用户登录系统时会发生这种情况。 ### [](https://octobercms.com/docs/database/relations#disable-deferred-binding)禁用延迟绑定 有时您可能需要完全禁用给定模型的延迟绑定,例如,如果要从单独的数据库连接中加载它。为此,您需要确保在运行内部save方法中的递延绑定钩子之前和之后,模型的`sessionKey`属性是正确`null`的。为此,您可以绑定到模型的`model.saveInternal`事件: ~~~ public function __construct() { $result = parent::__construct(...func_get_args()); $this->bindEvent('model.saveInternal', function () { $this->sessionKey = null; }); return $result; } ~~~ > **注意:**这将完全禁用对您应用此替代的任何模型的延迟绑定。