LoginSignup
0
0

More than 1 year has passed since last update.

Rails 月ごとのデータを出すときに31日のデータがなかったのでメモ

Last updated at Posted at 2022-09-14

投稿を月ごとに表示させたかったが31日のデータが表示されなかったので色々試した
結果的に発行されるSQLクエリが問題だった

元のコードとクエリ

config/application.rb
config.time_zone = 'Asia/Tokyo'
config.active_record.default_timezone = :local
controller
@month = params[:month] ? Date.parse(params[:month]) : Date.today
@diaries = current_user.diaries.where(created_at: @month.all_month).order(created_at: :asc)
SELECT "diaries".* FROM "diaries" WHERE "diaries"."user_id" = ? AND "diaries"."created_at" BETWEEN ? AND ? ORDER BY "diaries"."created_at" ASC  [["user_id", 13], ["created_at", "2022-08-01"], ["created_at", "2022-08-31"]]

これだと2022-08-31の00:00:00までのデータを取得することになるせいで31日のデータが得られない

解決

@diaries = current_user.diaries.where(created_at: @month.in_time_zone.all_month).order(created_at: :asc)
SELECT "diaries".* FROM "diaries" WHERE "diaries"."user_id" = ? AND "diaries"."created_at" BETWEEN ? AND ? ORDER BY "diaries"."created_at" ASC  [["user_id", 13], ["created_at", "2022-07-31 15:00:00"], ["created_at", "2022-08-31 14:59:59.999999"]]

これで時間までを検索に入れることが出来て31日の最後の時間までが得られた

解決までの道のり

理由がわからなかったのでとりあえずタイムゾーンを戻してみた
→ダメ

all_monthがダメなのかとコードを変更

@diaries = current_user.diaries.where(created_at: @month.beginning_of_month...@month.end_of_month).order(created_at: :asc)

結果変わらず
ここではじめてSQLを確認したら
"created_at" >= ? AND "diaries"."created_at"だったので調べてみる
>=がcreated_atまでってことだと分かったので次の日を指定してあげれば!?ってことで修正

@diaries = current_user.diaries.where(created_at: @month.beginning_of_month...@month.next_month.beginning_of_month).order(created_at: :asc)

31日も表示された!!!!
と思ったけどTimezoneを東京に戻してみたら時差分の9時までが先月分になってしまった

ここからDBのwhereを日本時間にしようとしたりいろいろ検索してだいぶ時間がかかった
どこかの記事でall_monthの前にin_time_zoneを入れているのを発見して解決

Timezoneの比較

デフォルト
SELECT "diaries".* FROM "diaries" WHERE "diaries"."user_id" = ? AND "diaries"."created_at" BETWEEN ? AND ? ORDER BY "diaries"."created_at" ASC  [["user_id", 13], ["created_at", "2022-08-01 00:00:00"], ["created_at", "2022-08-31 23:59:59.999999"]]

東京
SELECT "diaries".* FROM "diaries" WHERE "diaries"."user_id" = ? AND "diaries"."created_at" BETWEEN ? AND ? ORDER BY "diaries"."created_at" ASC  [["user_id", 13], ["created_at", "2022-07-31 15:00:00"], ["created_at", "2022-08-31 14:59:59.999999"]]

解決まで6時間もかかってしまった
もっと勉強せねば

まとめ

Timezoneを変更したときはちょっと注意しないといけない
sqlクエリを確認すること
期間選択する場合は時間までいれること

0
0
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
0