ねこものがたり

いちにちいっぽ

DBから前後のデータをとってくる

何がしたいか

reportというモデルがある。 report/showを開いた時に、開いているreportの前後のreportページに行けるようにリンクを貼りたい。

どうやって前後の情報をとるか

一番いいのはreportモデルにuuidを使うことのようです。

教えてもらった記事:rails+postgresでidにuuidを使う - komagataのブログ

でも今回はuuidではなくてcreated_atを使って見ているreportより1つ古い/新しいreport」をとってくるようにメソッドを書きました。

def previous
    Report.order(created_at: :desc).where(user_id: user_id).find_by("created_at < ?", created_at)
end

  
def next
    Report.order(created_at: :asc).where(user_id: user_id).find_by("created_at > ?", created_at)
end

データを整列させて条件を指定する

Report.order(created_at: :desc)とかReport.order(created_at: :asc)というのは、たくさんんのreportをcreated_atを基準に降順昇順にするということ。

created_at順にきれいに並べた上で、.where(user_id: user_id)現在表示中のreportを書いたユーザーと同じ人が書いたreportに絞っていく。

そしてfind_by("created_at < ?", created_at)では表示中のreportよりcreate_atが小さい(つまり以前の日付)reportのうち最初の1件とってくる。 .find_by("created_at > ?", created_at)では反対に日付が大きい、新しいreportのうち最初の1件をとってくる。

注意すること

こういうメソッドを書く機会というのは多いらしく、よくやりがちだけれど気をつけなければならないミスというのを教えてもらいました。

等号不等号

< ,>, ≦, ≧。 イコールの有無、右向き左向き、ちょっとした違いが事故につながるそう。ここには書かないけどヤバそうな事例を聞きました。 数学苦手で凡ミスをやらかしがちな私としては、全然笑えなかった。 怖い!!!!

検索条件にするカラムと優先順位

上記のようにcreated_at、つまり時間に関することを条件に入れるときは、特に常に慎重でなければならないそうです。

時間に限らずテーブルがもつ情報の中で優先順位をつけたり、保存される情報にはどのような内容が考えられるのかできる限り様々なことを想定することでしかるべきときに事故が起きないようにするという姿勢を教えてもらいました。

以上を踏まえてもう少し改善したい

最初に書いたメソッドはちゃんと使えるんですが、今現在「同じcreated_atをもつreportがあったらどうするか」を考えています。 正確に言うと「考えてみよう」とアドバイスをいただきました。

ぶっちゃけ全然わからなくて「そんなことは起きない」と愚痴ってたら「それがそうでもない」と。(!!)

なのでめげずに考え中です。