前提・実現したいこと
現在ストップウォッチ機能の付いたTodoアプリのプログラムを書いています。
再読み込みしても時刻が測り続けられるようにTaskモデルのDBにストップウォッチの「計測開始時刻」と経過時刻を保存しようとしています。
ところが、javascriptで取得した「計測開始時刻」の値がうまくDB(sqlite3)に反映されず、変な時刻が保存されてしまいます。
処理の流れとしては、
①javascript内でDate型のデータで「測定開始時刻」を取得。
②ajaxを用いて、railsのコントローラに送信
③ajaxで送られたデータをコントローラ内でrubyの仕様に変換
④変換した情報をデータベースに格納
を想定しています。
ただ、いろんな方法を試しても例えば現在時刻が「2020-12-30 10:44:40 +0900」で、コントローラ内でその日付を変数timeに格納し、@task.update(started_at: time)とデータを更新しても、なぜかDBには「2000-01-01 01:42:48.362460」という見当違いな日付が保存されてしまいます。
つまり、コントローラ内で正しい現在時刻を取得でき、変数に格納できており、なおかつ対象モデルにその値も渡せているのにDBには正しい日付が格納されません。
DBに正しく日付を格納する方法もしくは問題の本質をご存じの方はご教授いただけると嬉しいです!
発生している問題・エラーメッセージ
ログです
Started PATCH "/tasks/ajaxupdate" for ::1 at 2020-12-30 10:30:12 +0900 (0.2ms) SELECT sqlite_version(*) Processing by TasksController#ajaxupdate as JSON Parameters: {"task_id"=>"2", "started_at"=>"1609291812.371"} User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]] Task Load (0.8ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]] ↳ app/controllers/tasks_controller.rb:35:in `ajaxupdate' 2020-12-30 10:30:12 +0900 (0.1ms) begin transaction ↳ app/controllers/tasks_controller.rb:39:in `ajaxupdate' Task Update (4.1ms) UPDATE "tasks" SET "start_at" = ?, "updated_at" = ? WHERE "tasks"."id" = ? [["start_at", "2000-01-01 01:30:12"], ["updated_at", "2020-12-30 01:30:13.080950"], ["id", 2]] ↳ app/controllers/tasks_controller.rb:39:in `ajaxupdate' (3.1ms) commit transaction ↳ app/controllers/tasks_controller.rb:39:in `ajaxupdate' Completed 200 OK in 95ms (Views: 0.7ms | ActiveRecord: 8.7ms | Allocations: 18578)
pry-byebugでコントローラ内で何が起こっているのか確認したときのものです。
[1] pry(#<TasksController>)> params[:started_at] => "1609292052.706" [2] pry(#<TasksController>)> Time.at(params[:started_at].to_i) => 2020-12-30 10:34:12 +0900 => 2020-12-30 10:34:12 +0900 time => 2020-12-30 10:34:12 +0900 time (0.2ms) begin transaction@task.update(start_at: time) ↳ (pry):5:in `ajaxupdate' Task Update (67.0ms) UPDATE "tasks" SET "start_at" = ?, "updated_at" = ? WHERE "tasks"."id" = ? [["start_at", "2000-01-01 01:34:12"], ["updated_at", "2020-12-30 01:38:10.218553"], ["id", 2]] ↳ (pry):5:in `ajaxupdate' (10.2ms) commit transaction ↳ (pry):5:in `ajaxupdate' => true (0.1ms) begin transaction@task.update(start_at: Time.now) ↳ (pry):6:in `ajaxupdate' Task Update (76.9ms) UPDATE "tasks" SET "start_at" = ?, "updated_at" = ? WHERE "tasks"."id" = ? [["start_at", "2000-01-01 01:42:48.362460"], ["updated_at", "2020-12-30 01:42:48.363578"], ["id", 2]] ↳ (pry):6:in `ajaxupdate' (8.0ms) commit transaction ↳ (pry):6:in `ajaxupdate' => true [7] pry(#<TasksController>)> @task.update(start_at: DateTime.now) (0.2ms) begin transaction ↳ (pry):7:in `ajaxupdate' Task Update (4.4ms) UPDATE "tasks" SET "start_at" = ?, "updated_at" = ? WHERE "tasks"."id" = ? [["start_at", "2000-01-01 01:43:21.851225"], ["updated_at", "2020-12-30 01:43:21.854037"], ["id", 2]] ↳ (pry):7:in `ajaxupdate' (9.4ms) commit transaction ↳ (pry):7:in `ajaxupdate' => true [8] pry(#<TasksController>)> Datetime.now NameError: uninitialized constant TasksController::Datetime Did you mean? DateTime from (pry):8:in `ajaxupdate' [9] pry(#<TasksController>)> DateTime.now => Wed, 30 Dec 2020 10:43:48 +0900 [10] pry(#<TasksController>)> Time.now => 2020-12-30 10:44:40 +0900 [11] pry(#<TasksController>)> @task.update(start_at: DateTime.now) (0.1ms) begin transaction ↳ (pry):11:in `ajaxupdate' Task Update (7.3ms) UPDATE "tasks" SET "start_at" = ?, "updated_at" = ? WHERE "tasks"."id" = ? [["start_at", "2000-01-01 01:45:08.679773"], ["updated_at", "2020-12-30 01:45:08.680477"], ["id", 2]] ↳ (pry):11:in `ajaxupdate' (5.2ms) commit transaction ↳ (pry):11:in `ajaxupdate' => true
該当のソースコード
javascript
1started_at = new Date(); //現在時刻 2 3 $.ajax({ 4 type: "patch", 5 url: "/tasks/ajaxupdate", 6 data: { task_id: task_id, started_at: started_at.getTime()/1000 }, //javascriptとrubyではDateのデータ型の仕様が異なるので、処理を施しています 7 dataType: "json", 8 })
ruby
1def ajaxupdate 2 3 @task = Task.find(params[:task_id]) 4 time = Time.at(params[:started_at].to_i)#timeの中身を確認したところきちんと正しい現在時刻が格納されています! 5 @task.update(start_at: time) 6ned
Tasksテーブルの構造
t.string "taskname", null: false t.date "limit", null: false t.string "state", default: "0", null: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.time "start_at" t.float "working_on"
試したこと
まずは、JavaScriptで取得したDateデータがRailsコントローラで正しく使えていないことを想定し、データ型の違いを埋める処理を行った。
次にそもそもTaskを更新するときにただしい現在時刻が遅れていないのではと考え、pry-byebugを使い更新するときに用いるtime変数の中身を確認。しかし、きちんと正しい値が格納されていた。
TimeオブジェクトでなくDateTimeオブジェクトでないと保存できないのではないかと思い、pry-byebugで試してみたがどちらも変な日付がDBに格納されてしまった
ログを見てもtaskの更新の時に何か起こっているとしかわからず断念し、質問中です!
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
###補足
足りない情報は随時更新しますのでお知らせください。
また答えでなくともヒントやアドバイスでもすごく助かりますので知っている情報は何でも教えていただけると幸いです。
何卒よろしくお願いいたします!
回答1件
あなたの回答
tips
プレビュー