フックとスコープ
クエリをカスタマイズします
「フックとスコープ」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
フックとスコープ
GORMには2つのカスタマイズ機能があります。フックはライフサイクルイベントの前後でコードを自動的に実行し、スコープは再利用可能なクエリロジックをまとめます。これらを組み合わせることで、データアクセスを整理し、一貫性を保てます。
フックとは
フックはモデルに定義するメソッドで、GORMが操作の前後に呼び出します。BeforeCreate、AfterCreate、BeforeUpdate、BeforeDelete などがあります。
BeforeCreateフック
モデルに正しいシグネチャのメソッドを定義します。ここでは、レコードが挿入される前にUUIDを設定します。
func (u *User) BeforeCreate(tx *gorm.DB) error {
u.UUID = uuid.NewString()
return nil
}フックでのバリデーション
フックからエラーを返すと、操作を中止できます。GORMは周囲のトランザクションをロールバックするため、不正なデータがデータベースに到達することはありません。
func (u *User) BeforeSave(tx *gorm.DB) error {
if u.Age < 0 {
return errors.New("age cannot be negative")
}
return nil
}フックはトランザクション内で実行される
tx *gorm.DB 引数は、GORMが使用しているトランザクションです。フック内で関連データを書き込む場合は、この tx を使用してください。メインの操作と一緒にアトミックにコミットまたはロールバックできます。
スコープとは
スコープとは、*gorm.DBを受け取り、*gorm.DBを返す関数で、クエリの一部をカプセル化したものです。db.Scopes(...)で適用し、複数のクエリで再利用できます。
func ActiveUsers(db *gorm.DB) *gorm.DB {
return db.Where("active = ?", true)
}スコープの適用
Scopesに1つ以上のスコープを渡します。スコープは組み合わせられるため、フィルターを宣言的に組み合わせて最終的なクエリを作成できます。
db.Scopes(ActiveUsers, Recent).Find(&users)実行可能なフックとスコープのシミュレーション
GORMにはデータベースが必要なため、この実行可能な例では、通常の関数を使ってBeforeCreateフックと再利用可能なスコープに似たフィルターをシミュレートします。
package main
import (
"errors"
"fmt"
)
type User struct {
Name string
Age int
Active bool
}
func beforeCreate(u *User) error {
if u.Age < 0 {
return errors.New("age cannot be negative")
}
if u.Name == "" {
u.Name = "anonymous"
}
return nil
}
func activeOnly(users []User) []User {
var out []User
for _, u := range users {
if u.Active {
out = append(out, u)
}
}
return out
}
func main() {
u := User{Age: 30, Active: true}
if err := beforeCreate(&u); err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("created:", u.Name)
all := []User{u, {Name: "Lin", Active: false}}
fmt.Println("active count:", len(activeOnly(all)))
}ページネーション用のスコープ
よく使われるスコープとして、ページ番号からページネーションを生成するものがあります。OffsetとLimitをカプセル化することで、すべての一覧エンドポイントで同じ方法でページネーションできます。
func Paginate(page, size int) func(*gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Offset((page - 1) * size).Limit(size)
}
}フックとアプリケーションロジックの違い
フックは、タイムスタンプ、スラッグ、監査フィールドなどの横断的関心事を一元管理します。動作を予測しやすくテスト可能に保つため、複雑なビジネスロジックはフックではなくサービスに置いてください。
フックのスキップ
一括操作では、db.Session(&gorm.Session{SkipHooks: true})を使ってフックを無効にできます。大規模なインポートは高速化しますが、バリデーションもスキップされるため、注意して使用してください。
クイックチェック
フックとスコープの知識を確認しましょう。
まとめ
フックとスコープについて学びました。
- フックはライフサイクルイベントの前後で実行され、エラーを返すと処理を中止してロールバックします
- フックはtx引数を通じてトランザクション内で実行されます
- スコープは再利用可能な*gorm.DB関数で、Scopesを使って適用します
- フィルターとページネーションにはスコープを使用します
- 一括処理ではSkipHooksによってフックをバイパスできます
よくある質問
「フックとスコープ」レッスンは無料ですか?
はい。「フックとスコープ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「フックとスコープ」で何を学びますか?
クエリをカスタマイズします ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「フックとスコープ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- モデルとAutoMigrate
- CRUD操作
- 関連付け
- フックとスコープ