コメント欄に運営アイコンと非表示ユーザアイコンを表示、削除済ユーザのコメント表示
完成後
問題
コメントしたことのあるユーザが削除された場合というのは想定ができておらず、コメント欄に削除ユーザの名前が残り続けてそこをクリックすると、当然そのIDはないのでエラー画面が出てしまう。もちろんBefore_Actionで制御ができるが、見た目も削除されたユーザは非表示等にする必要があった。
工夫した点
アイコンを表示する際に、例えばuser.admin?等のメソッドを使うことになるが、もしコメント欄に削除済のユーザがいた場合、その処理はeach文のなかなので削除済のユーザのIDに対しても.admin?が行われてしまい、エラーが出てしまう問題が生じた。
そこで、以下のように回ってきた変数がnilではない時のみ、.admin?や.private?といったインスタンスが前提のメソッドを使うように工夫することで問題は解決できた。
また、非公開ユーザのコメントも許可する仕様なので、公開ユーザは非公開ユーザのプロフィールリンクへ飛ぶ可能性がある。もちろんアクセス制御はしているので”非公開ユーザーです”とでるのだが、リダイレクト先が今はIndexのみなのでそこも下のようにして分岐させた。昨日見つけたRequest Refererで元々いたページを取得し、それを条件式にし、自分のプロフィールページにいたときはそこに戻るようにした。ちなみにparamsには非公開ユーザのIDが入っているのでそこからとるとリダイレクトが無限に続くことになる。(Googleがエラーを出してくれる) 非公開ユーザIDアクセス→Privateで弾かれる→そのメソッドでまた非公開ユーザにリダイレクト→またPrivateで弾かれる・・・・となる。
→追記1 request.referer自体を変数展開すればリクエストを送った前のページを取得できるとわかったので下記のように変更。
ちなみにrequest.refererの中身をビューでみてみるとこんな感じ。
これで他人のプロフィールをみていて、そこの非公開ユーザのコメントからそこに跳ぼうとしても、みていたページで注意メッセージがでるようになる。
request.refererを使わなければ、他人のページから非公開ユーザへのリンクには対応できなかった。
→追記2 変数展開は必要ないので、変数展開は削除した。(Rails Tutorialでもあった・・・。)
削除済ユーザへのアクセス制御
削除されたユーザにアクセスするリンクは配置されていないが、削除されたユーザのIDを直接URLに入れてアクセスされることが考えられる。
そこでBefore_Actionで投げられたURLのIDからユーザをチェックし、いなければ注意フラッシュを出すメソッドを追加した。なお、showアクションは、インスタンスを前提とするメソッド.private?などを使うBefore_action privateもフィルターとしてあるので、その前に存在チェックのBefore_actionを入れないと、存在しないIDからインスタンスが生成されようとしてそこからメソッドが実行されてPrivateのBefore_actionはエラーを吐いてしまうため、順番にも注意。
一つのレコードだとグラフに表示されない問題(グラフ表示には少なくとも日付の違う二つのデータが必要)
原因?
いろいろなデータをLineチャートに入れてみて、Lineチャートに入るデータの形がXXXX-XX-XXの時、表示されない問題が発生することがわかった。したがってXXXX年XX月XX日に変更すると、一つのレコードでもちゃんと表示される。原因はよくわからないが、問題のトリガーはわかったので、日付が保存される時に型をXXXX-XX-XXからXXXX年XX月XX日に変換するメソッドを間に入れて解決した。
1 paramsには、XXXX-XX-XXの形で日付データが入っている。まずはそれをstrptimeで下記のように変換。
2 さらにそれをXXXX年XX月XX日の形に変換し、保存する。
http://song-of-life.hatenablog.com/entry/2018/12/05/131231
まとめると、XXXX-XX-XX → Wed,XX Dec XXXX → XXXX年XX月XX日に変換して保存することで、グラフに一つしかデータがないときに表示されない問題を解決することができた。
Cf
であればそもそもXXXX年XX月XX日でユーザに入力させて保存すればいいのだが、それをするにはdate_selectをinputで使う必要がある。そうすると、date_selectはdate型しか送れないので、現状String型を採用しているcalc_dateコラムに入れることができない。
calc_dateコラムは、pluckで取得する時に、date属性の値であればすべてXXXX-XX-XXに変換されてしまうので、Stringに変えたという背景がある。
よって、String型で、XXXX年XX月XX日で保存するには、上のようにするしかないと考えた。
グラフ登録の際、日付を予期しないフォーマットで送るとエラーが出る問題。
問題
グラフ登録フォームには、予め日付データがこのように格納されているが、もちろん消すこともできる。
そして消した場合に、コントローラのアクション側でこのような値を期待しているので、送られた空白や変な形の日付は、変換できませんといったエラーが発生してしまった。
解決
初めはなぜ空白なのにValidationが機能しないんだと思ったが、Validationが働くのは.saveが行われるときで、ここで問題になっているのはそこまでのアクションにある部分であった。
したがって、アクションが行われる前になんらかのチェックを実装する必要があると考え、以下のようなBefore_actionを実装した。
このメソッドは、正規表現を使って送られたparamsが、XXXX-XX-XXであるかどうかをチェックし、マッチしなければ下いたページに遷移させるというBefore_actionである。
これによって、ユーザがアクション内の期待する日付フォーマット以外を送ってきても、エラーの原因になる変換はBefore_actionにより行われず、エラーがでることはなくなった。
何も記入せず登録しても、下のようになる。変な値を送られてもこうなる。
自分のコメントを強調
完成後
ビュー
投稿コメントのpost_idからUserを取得し、そのUserのIDがログイン中のユーザなら、つまり自分自身のコメントなら専用のCSSを適用するDivで囲っている。
CSS
全てビューで行っている。
これから
あとはHerokuにデプロイしたいのだが、存在しないURLを投げられた時にエラー画面が出てしまうのでそれをなんとかしたい。
それをしてからHerokuにデプロイする。目標は明日例外処理を解決して、明後日にはHerokuにデプロイしたい。多分画像アップロードとかグラフとかいろいろ問題が起きそうなので予習しておきたい。
気づいたこと
エラーを意識することの重要性
存在しないインスタンスからメソッドを使うとエラーがでるけど、存在しないユーザのインスタンスを生成したり、見つけたりするのではエラーはでない。
この記事でも何回かあったけど、このエラーは割とよく会うので、それをコーディングしている時から意識することで回避できるのではと思った。
例えばBefore_actionのcorrect_userチェックでは以下のように存在しないIDから探そうとしているがエラーは起きない。だけどこれを.admin?とかそういうメソッドを使うとそのインスタンスはnil or emptyではいけませんといったエラーが表示される。