RSpecの日付表示を、viewで使っているメソッドに合わせて修正
こんにちは、くになかです。
RSpecを学習したときに詰まったので、忘れないように書き残しておきます。
はじめに
実装途中のRSpecでテストが失敗するので、修正を行いました。
spec/system/task_spec.rb
it 'Taskを編集した場合、一覧画面で編集後の内容が表示されること' do visit edit_project_task_path(project, task) fill_in 'Deadline', with: Time.current click_button 'Update Task' click_link 'Back' expect(find('.task_list')).to have_content(Time.current.strftime('%Y-%m-%d')) expect(current_path).to eq project_tasks_path(project) end
上記のテストを実行した際に、時刻表示の実装が違ってたのでテストが失敗していました。
行ったこと
最初に修正を行った時は、日付の表示でテストが失敗していたので、表示形式を変更しました。
spec/system/task_spec.rb
it 'Taskを編集した場合、一覧画面で編集後の内容が表示されること' do visit edit_project_task_path(project, task) fill_in 'Deadline', with: Time.current click_button 'Update Task' click_link 'Back' # expect(find('.task_list')).to have_content(Time.current.strftime('%Y-%m-%d')) expect(find('.task_list')).to have_content(Time.current.strftime('%-m/%d %-H:%M')) #追加 expect(current_path).to eq project_tasks_path(project) end
このままでもテストは成功するのですが、strftimeで直接書き換えると、View側の表示の仕様が変わるとテストが失敗してしまいます。
なので、Viewで使用しているメソッドを使って変更する必要があります。
app/view/tasks/index.html.erb
<% @tasks.each do |task| %> <tr> <td><%= task.title %></td> <td><%= task.status %></td> <td><%= short_time(task.deadline) if task.deadline? %></td> <td><%= link_to 'Show', [@project, task] %></td> <td><%= link_to 'Edit', edit_project_task_path(@project, task) %></td> <td><%= link_to 'Destroy', [@project, task], method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %>
viewではshort_timeメソッドを使っているので、それを使って修正します。
spec/system/task_spec.rb
it 'Taskを編集した場合、一覧画面で編集後の内容が表示されること' do visit edit_project_task_path(project, task) fill_in 'Deadline', with: Time.current click_button 'Update Task' click_link 'Back' # expect(find('.task_list')).to have_content(Time.current.strftime('%-m/%d %-H:%M')) expect(find('.task_list')).to have_content(short_time(Time.current)) #追加 expect(current_path).to eq project_tasks_path(project) end
上記のように、strftimeメソッドからviewで使ってるshort_timeメソッドに修正しました。
しかし、テストを実行すると、以下のように失敗します。
原因を探してみたところ、ApplicationHelperを読み込んでいなかったのでメソッドが使えないようでした。
spec/rails_helper.rb
require 'spec_helper' ... RSpec.configure do |config| ... config.include ApplicationHelper #追加 end
config.include ApplicationHelperを追加すると、short_timeメソッドが使えるようになり、テストが成功しました。
参考文献
以上です。最後まで読んでいただきありがとうございます。
コメントの編集ボタンをajax化した際にはまったこと
こんにちは、くになかです。
学習したことの備忘録を書いて行きたいと思います。
はじめに
コメントの編集ボタンのajax化した際にはまったので、それの備忘録を書いていきます。
スクールの講師に質問して、問題が起きた際の解決の流れがなんとなく分かったので忘れないように書いておきます。
問題としては、コメントの編集ボタン押下時に、コメントは非表示になるのですが、テキストエリアが表示されないということが起きていました。
試してみたこと
debuggerを使って、検証ツールで確認してみたところ、commentIdの値は取得できました。
app / assets / javascipts/edit_content.js
$("#js-comment-" + commentId).hide(); $("#js-textarea-comment-box-" + commentId).show();
手前の$("#js-comment-" + commentId).hide();を単体で実行してみたところ、コメントを非表示にすることが出来ました。
次に$("#js-textarea-comment-box-" + commentId).show();を単体で実行してみると、テキストエリアを表示することが出来ました。
分かったこと
以上のことから、$("#js-textarea-comment-box-" + commentId).show();の処理の記載には問題がないので、サンプルコードと課題のアプリではHTMLの構成に違いがあることがわかりました。
HTMLを確認してみたところ、上記のようにjs-comment-73が外側のtrタグにもあるので、フォームもまとめて非表示になっている事がわかりました。
解決策
これらのことから、課題のアプリのtrタグのidを、”js-comment-<%= comment.id %>"から"comment-<%= comment.id %>”に変更したところ、フォームが正しく表示されるようになりました。
まとめ
どこまで処理ができているのかという点をできる限り具体化するために、処理の順番を変えてみたり、単体で実行してみたりすることで、正しく動作するか確認してみることが大切だと思いました。
以上です。最後まで読んでいただきありがとうございます。
kaminariを用いたページネーション機能の実装について
こんにちは、くになかです。
学習したことの備忘録を書いて行きたいと思います。
はじめに
投稿一覧ページにページネーションの機能を追加した際の備忘録を書いていきます。
gemのkaminariを使って実装しました。
ページネーションとは
多くなってしまった投稿などを複数のページに分割して、情報を読み取りやすくするナビゲーションのことを指します。
kaminariとは
Railsアプリケーションにページネーションを導入するためのgemです。
下記のように実行するとインストールできます。
gemfile
gem ‘kaminari'
terminal
$ bundle
kaminariの設定ファイルを作成・変更
下記のように実行してkaminari_config.rbを作成します。
terminal
$ rails g kaminari:config
作成したkaminari_config.rbを変更します。
config/initializers/kaminari_config.rb
Kaminari.configure do |config| # frozen_string_literal: true config.default_per_page = 20 # 今回は掲示板の表示数を20個にしたいので、config.default_per_pageを20にします。 # config.max_per_page = nil # config.window = 4 # config.outer_window = 0 # config.left = 0 # config.right = 0 # config.page_method_name = :page # config.param_name = :page # config.max_pages = nil # config.params_on_first_page = false end
initializersファイル配下にあるファイルを変更したらサーバーの再読み込みが必要なので、terminalでrails sを実行します。
terminal
$ rails s
ページネーションのデザインを変更
事前にテンプレートが用意されているので、をダウンロードすることで好きな見た目に変えることが出来ます。
今回はbootstrap4をダウンロードします。
terminal
$ rails g kaminari:veiws bootstrap4
controllerを編集
掲示板一覧のアクションにpage(params[:page])を追加します。
app/controllers/boards_controller.rb
def index @boards = Board.all.page(params[:page]).includes(%i[user bookmarks]).sorted end
viewを編集
view側に下記コードを入力することで、ページネーションを表示できます。
paginateメソッドでページネーションのテンプレートをrenderします。
app/views/boards/index.html.erb
<%= paginate @boards %>
まとめ
ページネーションはkaminariを使うことで簡単に実装できました。
initializersファイル配下にある設定ファイルを変更した時に、サーバーの再読み込みを忘れがちなので気をつけたいと思いました。
参考文献
https://github.com/kaminari/kaminari#configuring-kaminari%EF%BC%89
以上です。最後まで読んでいただきありがとうございます。
ブックマーク機能のAjax化について
こんばんは、くになかです。
学習したことの備忘録を書いて行きたいと思います。
はじめに
ブックマーク機能のAjax化する際の、javascriptを記載した時、分からなかったメソッドを書き残したいと思います。
JavaScriptのコード
ajax化するには、remote: trueなどもするのですが、今回はjs.erbの記述で詰まったのでそこについて書きます。
create.js.erb
$("#js-bookmark-button-for-board-<%= @board.id %>").replaceWith("<%= j(render('boards/unbookmark', board: @board)) %>”);
jメソッドについて
j(render …) の j は escape_javascriptのエイリアスメソッドです。
改行コード、シングルクオート、ダブルクオートの中を、エスケープしてくれるヘルパメソッドです。
使う理由としては、JavaScriptが読み取れる文字列に変換するためと、XSS対策のためだそうです。
今回の場合、render 'boards/unbookmark'なので、 app/views/boards/_unbookmark.html.erbで出力した文字列が入ります。
replaceWithメソッドについて
replaceWithメソッドは、1 回の呼び出しで DOM からコンテンツを削除し、HTML形式の文字列を渡しています。
htmlメソッドは要素をhtmlで返すのに対し、replaceWithメソッドは実際の要素(文字列)を返す感じです。
まとめ
javascriptに関してなれてない部分が多く、メソッドの使い方や文法などに戸惑いました。
ajax化する際やvue.jsなどのフレームワークを使う場合はjavascriptの知識が必須なのでなれておかないとなと思いました。
参考文献
https://api.jquery.com/replaceWith/ https://api.rubyonrails.org/v5.2.4/classes/ActionView/Helpers/JavaScriptHelper.html#method-i-escape_javascript
以上です。最後まで読んでいただきありがとうございます。
Rails: db:resetとdb:migrate:resetの違いについて
こんばんは、くになかです。
学習したことの備忘録を書いて行きたいと思います。
はじめに
テストを試してみたところ、以下のエラーが出たので、その解決方法を記載しています。
Rails / UniqueValidationWithoutIndex 一意性の検証には一意のインデックスを使用する必要があります。
解決方法
t.index [:user_id, :board_id], unique: true
以前、カラムに一意成約をつけるためにマイグレーションファイルに上記コードを追加しました。
それを反映させるために、rails db:resetをして再度rails db:migrateをしたのですが、変更されず一意性の検証エラーが出ました。
そのやり方は、適切ではなかったみたいです。
調べてみたところ、rails db:resetではマイグレーションファイルを編集していても、その内容は反映されないため、schema.rbは書き換わらないのです。
スキーマファイルを確認してみたところ、変更は適用されていませんでした。
t.index ["user_id", "board_id"], name: "index_bookmarks_on_user_id_and_board_id"
正しくはdb:migrate:resetでした。
db:migrate:reset はマイグレーションファイルを直接利用します。つまり、マイグレーションファイルの変更が反映されます。
実行し、スキーマファイルを確認してみたところ、変更が適用されていました。
t.index ["user_id", "board_id"], name: "index_bookmarks_on_user_id_and_board_id", unique: true
参考文献
以上です。最後まで読んでいただきありがとうございます。