はい!今やってます!

Work Pertly, Live Idly

GormのPreloadでorder by構文を使いたくなったとき

GormでPreloadの中でorder by 呼びたくなった場合、以下のような書き方(Preloadの中に記述)をすると、 Preloadの中身をよしなにorder byしてくれる。 Preloadの条件式(where)との併用も可能。

err := tx.
    Limit(limit).
    Offset(offset).
    Where("status = ?", TASK_STATUS_HOGE).
    Preload("ChildTasks", "status = ?", CHILD_TASK_STATUS_HOGE, func(db *gorm.DB) *gorm.DB {
        return db.Order("child_tasks.sort_order ASC")
    }).
    Find(&tasks).Error

この時実行されるSQLはこんな感じ。

api_1    | (/go/src/api/domain/repository/task_repository.go:29)
api_1    | [2019-11-15 12:02:12]  [3.84ms]  SELECT * FROM `tasks`  WHERE (status = 1) LIMIT 10 OFFSET 0
api_1    | [10 rows affected or returned ]
api_1    |
api_1    | (/go/src/api/domain/repository/task_repository.go:29)
api_1    | [2019-11-15 12:02:12]  [2.66ms]  SELECT * FROM `child_tasks`  WHERE (`task_id` IN (2,3,6,7,8,1,4,5,9,10)) AND (status = 1) ORDER BY child_tasks.sort_order ASC
api_1    | [18 rows affected or returned ]

たまに公式のドキュメントでも載ってないのがある。