0Pricing
Go Academy · レッスン

フックとスコープ

クエリをカスタマイズします

「フックとスコープ」は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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. モデルとAutoMigrate
  2. CRUD操作
  3. 関連付け
  4. フックとスコープ
← Go Academyに戻る