Kuni-Blog

Webエンジニア目指して勉強中/RUNTEQ 5月生/Ruby on Rails/沖縄出身/23歳

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メソッドに修正しました。

しかし、テストを実行すると、以下のように失敗します。 f:id:originals_92:20200811144047p:plain

原因を探してみたところ、ApplicationHelperを読み込んでいなかったのでメソッドが使えないようでした。

spec/rails_helper.rb

require 'spec_helper'
  ...
RSpec.configure do |config|
  ...
  config.include ApplicationHelper  #追加
end

config.include ApplicationHelperを追加すると、short_timeメソッドが使えるようになり、テストが成功しました。



参考文献

qiita.com



以上です。最後まで読んでいただきありがとうございます。

コメントの編集ボタンをajax化した際にはまったこと

こんにちは、くになかです。

学習したことの備忘録を書いて行きたいと思います。



はじめに

コメントの編集ボタンのajax化した際にはまったので、それの備忘録を書いていきます。

スクールの講師に質問して、問題が起きた際の解決の流れがなんとなく分かったので忘れないように書いておきます。

問題としては、コメントの編集ボタン押下時に、コメントは非表示になるのですが、テキストエリアが表示されないということが起きていました。



試してみたこと

debuggerを使って、検証ツールで確認してみたところ、commentIdの値は取得できました。 f:id:originals_92:20200621001832p:plain

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の構成に違いがあることがわかりました。

f:id:originals_92:20200621005724p:plain

HTMLを確認してみたところ、上記のようにjs-comment-73が外側のtrタグにもあるので、フォームもまとめて非表示になっている事がわかりました。



解決策

これらのことから、課題のアプリのtrタグのidを、”js-comment-<%= comment.id %>"から"comment-<%= comment.id %>”に変更したところ、フォームが正しく表示されるようになりました。 f:id:originals_92:20200621010511p:plain f:id:originals_92:20200621010540p:plain


まとめ

どこまで処理ができているのかという点をできる限り具体化するために、処理の順番を変えてみたり、単体で実行してみたりすることで、正しく動作するか確認してみることが大切だと思いました。



以上です。最後まで読んでいただきありがとうございます。

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

参考文献

qiita.com

以上です。最後まで読んでいただきありがとうございます。