2カ月間の勉強でしでかしたミス その1
ブログの更新はこの2カ月全くやってなかった一方で、学習の方は進めていたので、
その中でやってしまったミスを思い出せる範囲で書き残して行きます。
1)@消し忘れ
スクールで作成中のアプリで、コメント編集・削除のajax 化を行った後、テストを行ったら下のエラーが出て、何時間も難儀してました。
1) コメント コメントのCRUD コメントの削除 コメントを削除できること Failure/Error: within("#comment-#{comment_by_me.id}") do page.accept_confirm { find('.js-delete-comment-button').click } end Capybara::ElementNotFound: Unable to find css "#comment-1" [Screenshot]: tmp/screenshots/failures_r_spec_example_groups_nested_3_crud_nested_3_コメントを削除できること_123.png
掲示板にコメントを投稿できるようになっているのですが、コメントを投稿した直後はidが残っている一方で、リロードや別のページに移動してから戻ると、idが消えてました。そのせいでコメントのidが見つからず、削除できなくなってました。
原因
<tr id="comment-<%= @comment.id %>" >
コメント全体を上のtrタグでidをつけているのですが、本来はcomment.idの前に@は入りません。これが原因でコメントのidがうまくいってなかったようです。
2)コピペする時は要注意
1)よりも時間が遡っていますが、掲示板にコメントを保存・投稿できるようにする機能を実装した時のミスです。コメントを投稿しても全く反応せず、binding.pryで検証した結果、下のメッセージが帰ってきました。
[2] pry(#<CommentsController>)> ↳ app/controllers/comments_controller.rb:20 User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 11], ["LIMIT", 1]] ↳ app/controllers/comments_controller.rb:20 (0.1ms) rollback transaction ↳ app/controllers/comments_controller.rb:20 Redirected to http://localhost:3000/comments/55 Completed 302 Found in 6395ms (ActiveRecord: 1.1ms)
ちゃんとコメントが入っていることはbinding.pryで確認していたので、ストロングパラメータやバリデーション辺りが怪しいです。
原因
comments_controller.rb class CommentsController < ApplicationController before_action :require_login, only: %i[create index show] def show @board = Board.includes(:user).find(params[:id]) @comments = @board.comments.includes(:user).all @comment = @board.comments.build(user_id: current_user.id) if current_user end def index @comments = Comment.all.includes(:user).order(created_at: :desc) end def create @board = Board.find(params[:board_id]) @comments = @board.comments.includes(:board_id).all @comment = @board.comments.build(comment_params) @comment.user_id = current_user.id binding.pry if @comment.save flash[:success] = t('defaults.message.created', item: Comment.model_name.human) redirect_back(fallback_location: root_path) else flash.now[:danger] = t('defaults.message.not_created', item: Comment.model_name.human) redirect_back(fallback_location: root_path) @comment = @board.comments.build(comment_params) end end private def comment_params params.require(:comment).permit(:body, :user_id, :board_id) end end
予測は当たっていて、ストロングパラメータでboard.idをmergeしていないのが原因でした。ただ、私はさらにどこからか引っ張ってきた下のコードを書き、更に無駄な時間を浪費します。
def comment_params params.require(:comment).permit(:body).merge(params.permit(:user_id,:board_id))
end
上のコードだと、コメントの保存はできても、コメント作成失敗時にロールバックが発生して、エラーメッセージが表示されませんでした。正しいコードは次のコードです。
def comment_params params.require(:comment).permit(:body).merge(board_id:params[:board_id])
end
ストロングパラメータのmergeを調べればすぐに出てくるようなコードです。逆に修正前のコードはどこからコピってきたのか今では思い出せません。誰かのコードをコピペする時はしっかりそのコードが合っているかどうか調べましょう。
3)コピペする時は要注意 その2
コメント編集のajax化を行っている時にやってしまったミスです。コメントの編集ボタンを押して非同期で編集フォームを表示させようとしてjsファイルを書いていたのですが、ボタンを押してもうまくイベントが発火しない状態に陥ってました。
色々と調べて、passive:falseだのstopPropagationだの試していましたがうまく行きませんでした。最終的にはイベントが発火するようになりましたが、うまく行かなかった理由は本当にしょうもないミスです。
この時も参考にしたコードをコピペしてjsファイルに貼っていたのですが、修正前はコメントが```~#コメント更新ボタン~```となっていました。しかし、jsファイルのコメントの書き方は```~//コメント更新ボタン~```または/*コメント更新ボタン*/です。
まあ、一応ProgateでJavaScript学んでいたのですが、期間空いてしまって忘れてたんですよ...
結論 コピペする時は本当にそのコードが正しいか見極めてから行う
当方、エンジニア目指してる途中の初心者なので、検索したら出てくるコードが正しいか判断できる知識がまだありませんが、怪しいところがあったらしっかりと調べてから使うようにします。
まだまだミスはありますが、今回はこの3つにしておきます。今まで学んできたこともまとめていければと思っていますし、その過程で自分のやったミスを思い出したり、学習を進めていく中でまたミスが発生することもあるので、それらについてまた記録しておきたいですね。正直、こんなミスするかと言われたら否定できませんが、もしかしたら自分と同じような初心者の方に役立つことがあるかもしれませんし。
とりあえず、ブログ更新という名のアウトプットを頑張って行きたいと思います。