ranked-modelを使うときは :with_sameオプションを付けよう
前置き
自作中のTODOアプリではタスクの表示順を自由に入れ替えできるようになっています。
indexページには User の Task 一覧を表示
表示の順番はranked-model gemを使って :row_order
の値で制御
それぞれの Task はjQueryUIのsortableを導入してドラッグ&ドロップで入れ替えが可能
という感じです。
class Task < ApplicationRecord include RankedModel belongs_to :user scope :donetask, -> { where(:done => false ) } ranks :row_order, :scope => :donetask end
問題点
並び替えが上手くいかないときがある。
並び替えをしてページを更新すると、ひとつ下にズレたりすることがたびたびありました。
ログを見ると一応 :row_order の値はきちんと更新されています。
原因
新規にテストユーザーを作成し、タスクを4つ作成しました。
DB Browserで確認します。
1番目のタスクを1つ下(2と3のあいだ)へ移動すると :row_order の値が更新されます。
本来であれば、1番目のタスクの:row_order の値は「1162961895」と「1655222771」の間で設定されなければいけません。
では「-2146624780」は何かというと、これはデータベースに登録されたすべての Task のなかで上から2番目に位置する数値です。
(実際には「すべての未完了なタスク」が正しいです。Taskモデルの画像参照。)
データベース上の全てのタスクの中ではなく、そのユーザーが持っているタスクの中で順番を変更しないといけません。
対処法
ranks :row_orderに :with_same => :(親モデルの外部キー) というオプションを付け足します。
class Task < ApplicationRecord include RankedModel belongs_to :user scope :donetask, -> { where(:done => false ) } ranks :row_order, :scope => :donetask, :with_same => :user_id ←これ end
これでユーザーごと、つまり同じ user_id を持った複数の Task ごとにrow_orderの数値が割り振られるようになります。
長々と書きましたが、単純に「gemを使うときはREADMEを必ず読もうぜ」という話ですね。気をつけよう