はじめに
こんにちは、HappyManaです。
ranked-modelを使った際、既存レコードに値を入れる処理を書いたのですが、
ranked-modelのREADMEに書いてある方法で困ったことがあったため備忘録として書きます。
困ったこと
ranked-modelのREADMEには、以下の方法が書いてあります。
Duck.update_all('row_order = EXTRACT(EPOCH FROM created_at)')
これは、timestamp型のcreated_atをUNIX時間に変換するというものです。
UNIX時間は、1970年1月1日午前0時ちょうどからの経過秒数なので整数値になります。
なので並び替えのカラムの型をINTEGER型とすると、型としては問題はありせん。
しかし、created_atをUNIX時間に変換する際に、ミリ秒が四捨五入されるという処理になりました。
たとえば、created_atが2023-12-25T12:00:00.193967+09:00
のとき、UNIXに変換すると、1703473200となります。
また、2023-12-25T12:00:00.542731+09:00
のときは、1703473201になります。
このように、小数点以下1桁目で四捨五入されます。
こうなると、並び替え用のカラムに同じ値が入って同じ重みのレコードが複数でき、並び番号が同じになってしまいます。
そのため、既存のレコードに対してUNIXに変換した値を入れるのはよくないです。
どうするべきなのか
idなどユニーク制約がついたカラムを使って値を入れましょう。
Duck.update_all('row_order = id')
また、eachなどで回してインデックスを入れてもいいですが、N+1になるので、注意が必要です。