Hooks

Hooks は、モデル操作の前後に実行されるアクションです。

利用可能な Hooks

View モデル

View モデルでは以下の Hook が利用できます:

  • AfterSelectHooks - SELECT 操作の後に実行

Table モデル

Table モデルでは以下の Hooks が利用できます:

  • BeforeInsertHooks - INSERT 操作の前に実行
  • AfterInsertHooks - INSERT 操作の後に実行
  • BeforeUpsertHooks - UPSERT 操作の前に実行
  • AfterUpsertHooks - UPSERT 操作の後に実行
  • BeforeUpdateHooks - UPDATE 操作の前に実行
  • AfterUpdateHooks - UPDATE 操作の後に実行
  • BeforeDeleteHooks - DELETE 操作の前に実行
  • AfterDeleteHooks - DELETE 操作の後に実行

Writing a Hook

Hook 関数は以下の署名を持つ必要があります:

func myHook(ctx context.Context, exec bob.Executor, t T) (context.Context, error) {
    // Hook の処理をここに記述
    return ctx, nil
}

パラメータ

  • ctx context.Context - 操作のコンテキスト
  • exec bob.Executor - データベース実行器
  • t T - モデルのインスタンス

戻り値

  • context.Context - 更新されたコンテキスト(必要に応じて)
  • error - エラーが発生した場合のエラー

Registering hooks

Hook を登録するには、適切な Hook スライスに追加します:

userTable.BeforeUpdateHooks.Add(myHook)

例:更新前のタイムスタンプ設定

func setUpdatedAt(ctx context.Context, exec bob.Executor, user *User) (context.Context, error) {
    user.UpdatedAt = time.Now()
    return ctx, nil
}

// Hook を登録
userTable.BeforeUpdateHooks.Add(setUpdatedAt)

例:ログ記録

func logOperation(ctx context.Context, exec bob.Executor, user *User) (context.Context, error) {
    log.Printf("User operation: %+v", user)
    return ctx, nil
}

// 複数の Hook を登録
userTable.BeforeInsertHooks.Add(logOperation)
userTable.AfterInsertHooks.Add(logOperation)

Skipping hooks

特定の操作で Hook をスキップする場合は、bob.SkipHooks() を使用します:

// Hook をスキップして SELECT を実行
users, err := userTable.Query().Select(bob.SkipHooks(ctx), exec).All()

// Hook をスキップして INSERT を実行
_, err = userTable.Insert(bob.SkipHooks(ctx), exec, user)

使用例

// バリデーション Hook
func validateUser(ctx context.Context, exec bob.Executor, user *User) (context.Context, error) {
    if user.Email == "" {
        return ctx, errors.New("email is required")
    }
    return ctx, nil
}

// 監査ログ Hook
func auditUser(ctx context.Context, exec bob.Executor, user *User) (context.Context, error) {
    // 監査ログをデータベースに記録
    auditLog := AuditLog{
        TableName: "users",
        RecordID:  user.ID,
        Action:    "UPDATE",
        Timestamp: time.Now(),
    }
    
    _, err := auditTable.Insert(ctx, exec, auditLog)
    return ctx, err
}

// Hook を登録
userTable.BeforeUpdateHooks.Add(validateUser)
userTable.AfterUpdateHooks.Add(auditUser)

Hook は、データベース操作の前後で共通の処理を実行するための強力な仕組みです。バリデーション、ログ記録、監査、自動的なタイムスタンプ更新などに活用できます。