Ectoではテーブル定義でtimestampsを記述すると、追加日時inserted_at
と更新日時updated_at
が追加されます。
create table(:users) do
add :name, :string, null: false
timestamps()
end
updated_at
は、下記のようにレコードを更新したときに自動的に更新されます。
Railsを使っている人にもお馴染みでしょう。
user = Repo.get(User, 1)
Repo.update(User.changeset(user, %{name: "hoge"}))
時にはupdated_at
だけを更新したいことがあります。
しかし、次のコードでは更新が走らず、updated_at
も更新されません。
user = Repo.get(User, 1)
Repo.update(User.changeset(user))
Railsの場合は、touchを使いますが(参考: Railsでupdated_atのみ更新したい場合)、 Ectoではforceオプションを使って、強制的に更新を走らせます。
user = Repo.get(User, 1)
Repo.update(User.changeset(user), force: true)
HexDocsにも、きちんと説明が書いてあります。
By default, if there are no changes in the changeset, update/2 is a no-op. By setting this option to true, update callbacks will always be executed, even if there are no changes (including timestamps).
デフォルトでは、changesetに変更がない場合にはupdate/2は何もしない。このオプション(force)をtrueに設定することで、(timestampsで作られたカラムも含めて)changesetに変更がなくてもupdateコールバックは常に実行されるようになる。
また、Google Groupでは、Elixirの生みの親であるJose氏がHow to update updated_at onlyという質問に答えています。
You can pass a force: true option when you call Repo.update with an empty changeset
force: trueオプションを渡してRepo.updateを呼び出せば良い