LoginSignup
0
1

More than 3 years have passed since last update.

acts_as_listで並び替えたときに他のレコードのupdated_atを更新させない方法

Last updated at Posted at 2019-08-22

結論はコチラ

課題

acts_as_listを適用しているModelに対して、新規作成(new -> save)や並び替え(insert_at)したときに他のレコードも position が変わるので、 updated_at が更新されてしまう。

やりたいこと

新規作成や並び替えで他のレコードの updated_at が更新されないようにしたい。

前提

  • acts_as_list gem を入れている
  • Modelのカラムにpositionを追加している

やってみたこと

1.record_timestamps を使ってみる(NG)

Article.record_timestamps = false
Article.new.save
Article.record_timestamps = true

ログのクエリを見ると updated_at が更新されてしまっている。

UPDATE `article` SET `position` = (`article`.`position` - 1), `updated_at` = '2019-08-11 16:53:19' WHERE (1 = 1)

2. gemを調査

acts_as_list-0.9.19/lib/acts_as_list/active_record/acts/position_column_method_definer.rb#L45あたり

      define_singleton_method :update_all_with_touch do |updates|
        updates += touch_record_sql if touch_on_update
        update_all(updates)
      end

なるほど、 touch_on_update が怪しい。

3. gemのGithubを見てみた。

README.md を読んでみたが、特に touch_on_update の記載はなかったが、テストコードに以下の記述があった。

class SequentialUpdatesAltIdTouchDisabled < SequentialUpdatesAltId
  acts_as_list column: "pos", touch_on_update: false
end

なるほど、 touch_on_update: false を付けてみよう。

結論

  • touch_on_update: false を付けたら更新できた。
class Article < ActiveRecord::Base
  acts_as_list top_of_list: 0, add_new_at: :top, touch_on_update: false
end

ログのクエリを見ると updated_at が更新されていない。

UPDATE `article` SET `position` = (`article`.`position` - 1) WHERE (1 = 1)
  • 新規作成時: 他のレコードはpositionが +1 されるが、 updated_at は更新されない
  • 並び替え時: 動かしたレコードのみ updated_at が更新される。他もpositionは変わるが、updated_at は更新されない

ついでに

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1