857 lines
24 KiB
HTML
857 lines
24 KiB
HTML
|
|
<!DOCTYPE HTML>
|
|
<html lang="" >
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
|
<title>Callbacks · GORM Guide</title>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
<meta name="description" content="">
|
|
<meta name="generator" content="GitBook 3.2.3">
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="gitbook/style.css">
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="gitbook/gitbook-plugin-highlight/website.css">
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="gitbook/gitbook-plugin-search/search.css">
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="gitbook/gitbook-plugin-fontsettings/website.css">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<meta name="HandheldFriendly" content="true"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
|
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="gitbook/images/apple-touch-icon-precomposed-152.png">
|
|
<link rel="shortcut icon" href="gitbook/images/favicon.ico" type="image/x-icon">
|
|
|
|
|
|
<link rel="next" href="advanced.html" />
|
|
|
|
|
|
<link rel="prev" href="crud.html" />
|
|
|
|
|
|
</head>
|
|
<body>
|
|
|
|
<div class="book">
|
|
<div class="book-summary">
|
|
|
|
|
|
<div id="book-search-input" role="search">
|
|
<input type="text" placeholder="Type to search" />
|
|
</div>
|
|
|
|
|
|
<nav role="navigation">
|
|
|
|
|
|
|
|
<div class="book-summary">
|
|
|
|
<nav role="navigation">
|
|
<ul class="summary">
|
|
|
|
|
|
|
|
<li class="chapter " data-level="1.1" data-path="./">
|
|
|
|
<a href="./">
|
|
|
|
|
|
<b>1.1.</b>
|
|
|
|
Getting Started with GORM
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.2" data-path="database.html">
|
|
|
|
<a href="database.html">
|
|
|
|
|
|
<b>1.2.</b>
|
|
|
|
Database
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="1.2.1" data-path="database.html">
|
|
|
|
<a href="database.html#connecting-to-a-database">
|
|
|
|
|
|
<b>1.2.1.</b>
|
|
|
|
Database Connection
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.2.2" data-path="database.html">
|
|
|
|
<a href="database.html#migration">
|
|
|
|
|
|
<b>1.2.2.</b>
|
|
|
|
Migration
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.3" data-path="models.html">
|
|
|
|
<a href="models.html">
|
|
|
|
|
|
<b>1.3.</b>
|
|
|
|
Models
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="1.3.1" data-path="models.html">
|
|
|
|
<a href="models.html#model-definition">
|
|
|
|
|
|
<b>1.3.1.</b>
|
|
|
|
Model Definition
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.3.2" data-path="models.html">
|
|
|
|
<a href="models.html#conventions">
|
|
|
|
|
|
<b>1.3.2.</b>
|
|
|
|
Conventions & Overriding
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.3.3" data-path="associations.html">
|
|
|
|
<a href="associations.html">
|
|
|
|
|
|
<b>1.3.3.</b>
|
|
|
|
Associations
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="1.3.3.1" data-path="associations.html">
|
|
|
|
<a href="associations.html#belongs-to">
|
|
|
|
|
|
<b>1.3.3.1.</b>
|
|
|
|
Belongs To
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.3.3.2" data-path="associations.html">
|
|
|
|
<a href="associations.html#has-one">
|
|
|
|
|
|
<b>1.3.3.2.</b>
|
|
|
|
Has One
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.3.3.3" data-path="associations.html">
|
|
|
|
<a href="associations.html#has-many">
|
|
|
|
|
|
<b>1.3.3.3.</b>
|
|
|
|
Has Many
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.3.3.4" data-path="associations.html">
|
|
|
|
<a href="associations.html#many-to-many">
|
|
|
|
|
|
<b>1.3.3.4.</b>
|
|
|
|
Many To Many
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.3.3.5" data-path="associations.html">
|
|
|
|
<a href="associations.html#polymorphism">
|
|
|
|
|
|
<b>1.3.3.5.</b>
|
|
|
|
Polymorphism
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.3.3.6" data-path="associations.html">
|
|
|
|
<a href="associations.html#association-mode">
|
|
|
|
|
|
<b>1.3.3.6.</b>
|
|
|
|
Association Mode
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.4" data-path="crud.html">
|
|
|
|
<a href="crud.html">
|
|
|
|
|
|
<b>1.4.</b>
|
|
|
|
CRUD: Reading and Writing Data
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="1.4.1" data-path="crud.html">
|
|
|
|
<a href="crud.html#create">
|
|
|
|
|
|
<b>1.4.1.</b>
|
|
|
|
Create
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.4.2" data-path="crud.html">
|
|
|
|
<a href="crud.html#query">
|
|
|
|
|
|
<b>1.4.2.</b>
|
|
|
|
Query
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.4.3" data-path="crud.html">
|
|
|
|
<a href="crud.html#preloading-eager-loading">
|
|
|
|
|
|
<b>1.4.3.</b>
|
|
|
|
Preloading (Eager Loading)
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.4.4" data-path="crud.html">
|
|
|
|
<a href="crud.html#update">
|
|
|
|
|
|
<b>1.4.4.</b>
|
|
|
|
Update
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.4.5" data-path="crud.html">
|
|
|
|
<a href="crud.html#delete">
|
|
|
|
|
|
<b>1.4.5.</b>
|
|
|
|
Delete / Soft Delete
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.4.6" data-path="crud.html">
|
|
|
|
<a href="crud.html#associations">
|
|
|
|
|
|
<b>1.4.6.</b>
|
|
|
|
Associations
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li class="chapter active" data-level="1.5" data-path="callbacks.html">
|
|
|
|
<a href="callbacks.html">
|
|
|
|
|
|
<b>1.5.</b>
|
|
|
|
Callbacks
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.6" data-path="advanced.html">
|
|
|
|
<a href="advanced.html">
|
|
|
|
|
|
<b>1.6.</b>
|
|
|
|
Advanced Usage
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="1.6.1" data-path="advanced.html">
|
|
|
|
<a href="advanced.html#error-handling">
|
|
|
|
|
|
<b>1.6.1.</b>
|
|
|
|
Error Handling
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.6.2" data-path="advanced.html">
|
|
|
|
<a href="advanced.html#transactions">
|
|
|
|
|
|
<b>1.6.2.</b>
|
|
|
|
Transactions
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.6.3" data-path="advanced.html">
|
|
|
|
<a href="advanced.html#sql-builder">
|
|
|
|
|
|
<b>1.6.3.</b>
|
|
|
|
Raw SQL & SQL Builder
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.6.4" data-path="advanced.html">
|
|
|
|
<a href="advanced.html#generic-database-interface-sqldb">
|
|
|
|
|
|
<b>1.6.4.</b>
|
|
|
|
Generic database interface sql.DB
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.6.5" data-path="advanced.html">
|
|
|
|
<a href="advanced.html#compose-primary-key">
|
|
|
|
|
|
<b>1.6.5.</b>
|
|
|
|
Composite Primary Key
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.6.6" data-path="advanced.html">
|
|
|
|
<a href="advanced.html#logger">
|
|
|
|
|
|
<b>1.6.6.</b>
|
|
|
|
Overriding Logger
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.7" data-path="development.html">
|
|
|
|
<a href="development.html">
|
|
|
|
|
|
<b>1.7.</b>
|
|
|
|
Development
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="1.7.1" data-path="development.html">
|
|
|
|
<a href="development.html#architecture">
|
|
|
|
|
|
<b>1.7.1.</b>
|
|
|
|
Architecture
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.7.2" data-path="development.html">
|
|
|
|
<a href="development.html#write-plugins">
|
|
|
|
|
|
<b>1.7.2.</b>
|
|
|
|
Write Plugins
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.8" data-path="dialects.html">
|
|
|
|
<a href="dialects.html">
|
|
|
|
|
|
<b>1.8.</b>
|
|
|
|
Dialects
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="1.8.1" data-path="dialects.html">
|
|
|
|
<a href="dialects.html#dialect-specific-columns">
|
|
|
|
|
|
<b>1.8.1.</b>
|
|
|
|
Dialect Specific Columns
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.9" data-path="changelog.html">
|
|
|
|
<a href="changelog.html">
|
|
|
|
|
|
<b>1.9.</b>
|
|
|
|
Change Log
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="divider"></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="book-body">
|
|
|
|
<div class="body-inner">
|
|
|
|
|
|
|
|
<div class="book-header" role="navigation">
|
|
|
|
|
|
<!-- Title -->
|
|
<h1>
|
|
<i class="fa fa-circle-o-notch fa-spin"></i>
|
|
<a href="." >Callbacks</a>
|
|
</h1>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="page-wrapper" tabindex="-1" role="main">
|
|
<div class="page-inner">
|
|
|
|
<div id="book-search-results">
|
|
<div class="search-noresults">
|
|
|
|
<section class="normal markdown-section">
|
|
|
|
<h1 id="callbacks">Callbacks</h1>
|
|
<!-- toc -->
|
|
<p>You could define callback methods to pointer of model struct, it will be called when creating, updating, querying, deleting, if any callback returns an error, gorm will stop future operations and rollback all changes.</p>
|
|
<h3 id="creating-an-object">Creating An Object</h3>
|
|
<p>Available Callbacks for creating</p>
|
|
<pre><code class="lang-go"><span class="hljs-comment">// begin transaction</span>
|
|
BeforeSave
|
|
BeforeCreate
|
|
<span class="hljs-comment">// save before associations</span>
|
|
<span class="hljs-comment">// update timestamp `CreatedAt`, `UpdatedAt`</span>
|
|
<span class="hljs-comment">// save self</span>
|
|
<span class="hljs-comment">// reload fields that have default value and its value is blank</span>
|
|
<span class="hljs-comment">// save after associations</span>
|
|
AfterCreate
|
|
AfterSave
|
|
<span class="hljs-comment">// commit or rollback transaction</span>
|
|
</code></pre>
|
|
<h3 id="updating-an-object">Updating An Object</h3>
|
|
<p>Available Callbacks for updating</p>
|
|
<pre><code class="lang-go"><span class="hljs-comment">// begin transaction</span>
|
|
BeforeSave
|
|
BeforeUpdate
|
|
<span class="hljs-comment">// save before associations</span>
|
|
<span class="hljs-comment">// update timestamp `UpdatedAt`</span>
|
|
<span class="hljs-comment">// save self</span>
|
|
<span class="hljs-comment">// save after associations</span>
|
|
AfterUpdate
|
|
AfterSave
|
|
<span class="hljs-comment">// commit or rollback transaction</span>
|
|
</code></pre>
|
|
<h3 id="deleting-an-object">Deleting An Object</h3>
|
|
<p>Available Callbacks for deleting</p>
|
|
<pre><code class="lang-go"><span class="hljs-comment">// begin transaction</span>
|
|
BeforeDelete
|
|
<span class="hljs-comment">// delete self</span>
|
|
AfterDelete
|
|
<span class="hljs-comment">// commit or rollback transaction</span>
|
|
</code></pre>
|
|
<h3 id="querying-an-object">Querying An Object</h3>
|
|
<p>Available Callbacks for querying</p>
|
|
<pre><code class="lang-go"><span class="hljs-comment">// load data from database</span>
|
|
<span class="hljs-comment">// Preloading (edger loading)</span>
|
|
AfterFind
|
|
</code></pre>
|
|
<h3 id="callback-examples">Callback Examples</h3>
|
|
<pre><code class="lang-go"><span class="hljs-keyword">func</span> (u *User) BeforeUpdate() (err error) {
|
|
<span class="hljs-keyword">if</span> u.readonly() {
|
|
err = errors.New(<span class="hljs-string">"read only user"</span>)
|
|
}
|
|
<span class="hljs-keyword">return</span>
|
|
}
|
|
|
|
<span class="hljs-comment">// Rollback the insertion if user's id greater than 1000</span>
|
|
<span class="hljs-keyword">func</span> (u *User) AfterCreate() (err error) {
|
|
<span class="hljs-keyword">if</span> u.Id > <span class="hljs-number">1000</span> {
|
|
err = errors.New(<span class="hljs-string">"user id is already greater than 1000"</span>)
|
|
}
|
|
<span class="hljs-keyword">return</span>
|
|
}
|
|
</code></pre>
|
|
<p>Save/Delete operations in gorm are running in transactions, so changes made in that transaction are not visible unless it is commited.
|
|
If you want to use those changes in your callbacks, you need to run your SQL in the same transaction. So you need to pass current transaction to callbacks like this:</p>
|
|
<pre><code class="lang-go"><span class="hljs-keyword">func</span> (u *User) AfterCreate(tx *gorm.DB) (err error) {
|
|
tx.Model(u).Update(<span class="hljs-string">"role"</span>, <span class="hljs-string">"admin"</span>)
|
|
<span class="hljs-keyword">return</span>
|
|
}
|
|
</code></pre>
|
|
<pre><code class="lang-go"><span class="hljs-keyword">func</span> (u *User) AfterCreate(scope *gorm.Scope) (err error) {
|
|
scope.DB().Model(u).Update(<span class="hljs-string">"role"</span>, <span class="hljs-string">"admin"</span>)
|
|
<span class="hljs-keyword">return</span>
|
|
}
|
|
</code></pre>
|
|
|
|
|
|
</section>
|
|
|
|
</div>
|
|
<div class="search-results">
|
|
<div class="has-results">
|
|
|
|
<h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
|
|
<ul class="search-results-list"></ul>
|
|
|
|
</div>
|
|
<div class="no-results">
|
|
|
|
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<a href="crud.html#associations" class="navigation navigation-prev " aria-label="Previous page: Associations">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
|
|
<a href="advanced.html" class="navigation navigation-next " aria-label="Next page: Advanced Usage">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<script>
|
|
var gitbook = gitbook || [];
|
|
gitbook.push(function() {
|
|
gitbook.page.hasChanged({"page":{"title":"Callbacks","level":"1.5","depth":1,"next":{"title":"Advanced Usage","level":"1.6","depth":1,"path":"advanced.md","ref":"advanced.md","articles":[{"title":"Error Handling","level":"1.6.1","depth":2,"anchor":"#error-handling","path":"advanced.md","ref":"advanced.md#error-handling","articles":[]},{"title":"Transactions","level":"1.6.2","depth":2,"anchor":"#transactions","path":"advanced.md","ref":"advanced.md#transactions","articles":[]},{"title":"Raw SQL & SQL Builder","level":"1.6.3","depth":2,"anchor":"#sql-builder","path":"advanced.md","ref":"advanced.md#sql-builder","articles":[]},{"title":"Generic database interface sql.DB","level":"1.6.4","depth":2,"anchor":"#generic-database-interface-sqldb","path":"advanced.md","ref":"advanced.md#generic-database-interface-sqldb","articles":[]},{"title":"Composite Primary Key","level":"1.6.5","depth":2,"anchor":"#compose-primary-key","path":"advanced.md","ref":"advanced.md#compose-primary-key","articles":[]},{"title":"Overriding Logger","level":"1.6.6","depth":2,"anchor":"#logger","path":"advanced.md","ref":"advanced.md#logger","articles":[]}]},"previous":{"title":"Associations","level":"1.4.6","depth":2,"anchor":"#associations","path":"crud.md","ref":"crud.md#associations","articles":[]},"dir":"ltr"},"config":{"plugins":["github","edit-link"],"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"pluginsConfig":{"fontsettings":{"theme":"night","family":"sans","size":2},"github":{"url":"https://github.com/jinzhu/gorm"},"edit-link":{"label":"Edit This Page","base":"https://github.com/jinzhu/gorm/edit/gh-pages/documents/"},"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"theme":"default","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"GORM Guide","gitbook":"*"},"file":{"path":"callbacks.md","mtime":"2018-02-09T00:12:01.491Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2018-02-09T00:14:37.173Z"},"basePath":".","book":{"language":""}});
|
|
});
|
|
</script>
|
|
</div>
|
|
|
|
|
|
<script src="gitbook/gitbook.js"></script>
|
|
<script src="gitbook/theme.js"></script>
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-github/plugin.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-edit-link/plugin.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-search/search-engine.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-search/search.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-sharing/buttons.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|
|
|