20200619のRailsに関する記事は14件です。

【Rails】ancestryを用いた多階層カテゴリー機能の実装『seed編』

開発環境

・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

前提

下記実装済み。

投稿機能実装
多対多のカテゴリー機能実装
多階層カテゴリー機能実装(準備編)

実装

id name ancestry
1 ビジネス nil
2 金融 1
3 1/2
4 為替 1/2
5 税金 1/2
6 経済 2
7 日本経済 1/6
8 国際経済 1/6
9 経営 3
10 経営学 1/9
11 戦略・攻略 1/9
12 企業・開業 1/9
13 マーケティング 4
14 経営学 1/13
15 戦略・攻略 1/13
16 企業・開業 1/13

本のカテゴリーに上記の様な親子関係を持たせたい場合は、以下の様にデータを作成します。

seed.rb
business = Category.create(name: 'ビジネス')
business_child_array = ['金融', '経済', '経営', 'マーケティング']
business_grandchild_array = [
  ['株', '為替', '税金'], # 金融の子
  ['日本経済', '国際経済'], # 経済の子
  ['経営学', '戦略・管理', '起業・開業'], # 経営の子
  ['広告', '営業', '開発'] # マーケティングの子
]

business_child_array.each_with_index do |child, i|
  child = business.children.create(name: child)
  business_grandchild_array[i].each do |grandchild|
    child.children.create(name: grandchild)
  end
end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

既読・未読判定機能の実装

既読・未読機能の実装方法

まず、簡単なブログ機能のあるrailsアプリがあるとします。
このアプリのブログ詳細画面に遷移した際に、既読となるような仕様で実装していきたいと思います。
※既読/未読機能を実装するために必要なコードのみ載せています。

ER図

9E62416E-211A-4FC1-B849-AE2B019E9D50_4_5005_c.jpeg

テーブル

  • user
  • blog
  • read

既読機能を実装するにあたって、userテーブルとblogテーブルの中間テーブルが必要になります。
そこで、readテーブルを作成しました。

readテーブルのカラム

  • user_id
  • blog_id
  • complete(boolean型)

completeカラムをboolean型とし、既読/未読を真偽値で取得するようにしました。

モデル

user.rb
class User < ApplicationRecord
  has_many :blogs
  has_many :reads, dependent: :destroy
end
blog.rb
class Blog < ApplicationRecord
  belongs_to :user
  has_many :reads, dependent: :destroy
end

read.rb
class Read < ApplicationRecord
  belongs_to :user
  belongs_to :blog
end

コントローラーの設定

blogs_controller
class BlogsController < ApplicationController

  def show
    @read = current_user.reads.update(complete: true)
  end

showメソッドに、「現在ログインしているユーザーがブログ詳細画面に飛んだら、既読になる。」という記述をし、@readに格納します。
complete: true = '既読'

ビューの設定

show.html.erb
<%= @read ? '既読' : '未読' %>

@read ? '既読' : '未読'」 は、三項演算子という記法で、「?」の前の記述(@read)が、
true(真)であれば:の左側の処理を実行('既読'という文字列の出力を実行)し、
false(偽)であれば:の右側の処理を実行('未読'という文字列の出力を実行)します。

以上のようにコードを記述してくと、ブログ詳細画面に遷移した際に
4FE0EDBE-6683-41E2-AE32-FB10EF2D5D40_4_5005_c.jpeg

このように「既読」という文字列を出力できるようになります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails 値を正規化する

値の正規化

ある規則に従うように情報を変換することを正規かと言います。
今回はフリガナとして入力された値が平仮名だった場合に正規化して
カタカナにするという正規化を行ってみます。

まずapp/models/concernsディレクトリにnormalizerを作成していきます。

string_normalizer.rb
require "nkf"

module StringNormalizer
  def normalize_as_furigana(text)
    NKF.nkf("-W -w -Z1 --katakana", text).strip if text
end

以下のコードが実際に正規化を行っています。

NKF.nkf("-W -w -Z1 --katakana", text).strip if text

指定される引数は以下のような意味です。

NKF#nkfメソッドの引数

フラグ 意味
-W 入力の文字コードがUTF-8
-w UTF-8で出力
-Z1 全角の英数字、記号、半角スペースを半角に変える
--katakana ひらがなをカタカナに変換

これで準備ができました。あとはモデル側でモジュールを組み込みましょう

model.rb
class UserController < ApplicationRecord
  include StringNormalizer

  before_validation do
    self.name_kana = normalize_as_furigana(name_kana)
  end

こんな感じでバリデーションを通す前にname_kanaで指定された属性を
ひらがな-> カタカナへ正規化することができました。

本日は以上です!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】ancestryを用いた多階層カテゴリー機能の実装『準備編』

開発環境

・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

前提

下記実装済み。

投稿機能実装
多対多のカテゴリー機能実装

実装

1.Gemを導入

Gemfile
# 追記
gem 'ancestry'
ターミナル
$ bundle

2.カラムを追加

データ量がかなり多くなるのでindexを張ります。

ターミナル
$ rails g migration AddAncestryToCategory ancestry:string:index
ターミナル
$ rails db:migrate
schema.rb
create_table "categories", force: :cascade do |t|
  t.string "name"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.string "ancestry"
  t.index ["ancestry"], name: "index_categories_on_ancestry"
end

3.モデルを編集

category.rb
# 追記
has_ancestry

has_ancestry
➡︎ ancestryを使える様になる。

メソッド一覧

メソッド名 返り値
parent 親レコードを取得
parent_id 親レコードのIDを取得
root レコードのルートを取得
root_id レコードのルートIDを取得
root?is_root? レコードがルートであれば、trueを返す
ancestors ルートで始まり、親で終わる、レコードの祖先を返す
ancestors? レコードに祖先(ルートノードではない)がある場合はtrueを返す
ancestor_ids レコードの祖先のIDを返す
path ルートで始まり、自己で終わる、レコードのパスを返す
path_ids ルートIDで始まり、 自己のIDで終わるパスのIDをリストで返す
children 子レコードを取得
child_ids 子レコードのIDを取得
has_parent?ancestors? レコードが親を持っていれば、trueを返す
has_children?children? レコードが子を持っていれば、trueを返す
is_childless?childless? レコードが子を持っていなければ、trueを返す
siblings 兄弟レコード(同じ階層のレコード)を返す
sibling_ids 兄弟レコード(同じ階層のレコード)のIDを返す
has_siblings?siblings? レコードの親に複数の子がある場合はtrueを返す
is_only_child?only_child? レコードが親の唯一の子である場合はtrueを返す
descendants 子レコード、孫レコード、曽孫レコード... を返す
descendant_ids 子レコード、孫レコード、曽孫レコード... のIDを返す
indirects 孫レコード以下を返す
indirect_ids 孫レコード以下のIDを返す
subtree 子孫と自己のモデルを返す
subtree_ids レコードのサブツリーのIDをリストで返す
depth ノードの深さを返す
parent_of?(node) このレコードを(node)の親にする
root_of?(node) このレコードを(node)のルートにする
ancestor_of?(node) (node)の祖先にはこのレコードが含まれる
child_of?(node) (node)はレコードの親
descendant_of?(node) (node)はこのレコードの祖先の1つ
indirect_of?(node) (node)はこのレコードの祖先の1つですが、親ではない

階層構造

親:ビジネス
子:経済
孫:日本経済、国際経済

本のカテゴリーに上記の様な親子関係を持たせたい場合は、以下の様にデータを作成します。

business = Category.create(name: 'ビジネス')

business_economy = business.children.create(name: '経済')

business_economy.children.create([{ name: '日本経済' }, { name: '国際経済' }])

カラム構造

id name ancestry
1 ビジネス nil
2 経済 1(親のid)
3 日本経済 1/2(親のid/子のid)
4 国際経済 1/2(親のid/子のid)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【enum】 rails enumを利用してデータの可読性をあげよう

【ゴール】

rails においてenumの使用

画面収録 2020-06-19 19.28.08.mov.gif

【メリット】

■ dbの可読性向上、管理しやすい
■ 日本語化にも応用が効く

【開発環境】

■ Mac OS catalina
■ Ruby on Rails (5.2.4.2)
■ Virtual Box:6.1
■ Vagrant: 2.2.7

【実装】

と言ってもとても簡単!!!!対象のモデルに追記するのみ

※①が一番簡単な書き方
※②だと日本語も可能

model/hoge.rb
 enum カラム名:[:任意の単語, :任意の単語, :任意の単語, :任意の単語]
 enum カラム名:{"任意の単語": 1,"任意の単語": 2.......}

※number_field をselectに変更する
※enumで設定した値を取得して、選択できるようになります。

hoge/_form.html.erb
<%= form.select :カラム名, モデル名.カラム名s.keys, :selected=>モデル名.カラム名s[カラム名] %>

以上

【合わせて読みたい】

■enumについて
https://web-camp.io/magazine/archives/16862

■form_withについて
https://qiita.com/tanaka-yu3/items/50f54f5d4f4b8dfe19f3

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails6でのcocoon

スクールではrails5で開発を行ってcocoonを使っていて、。同じ方法でrails6でも親子関係のテーブルに複数画像データを保存しようとしたら、追加ボタンが作動しなかった。備忘録として投稿

参考URL

https://www.botreetechnologies.com/blog/introducing-jquery-in-rails-6-using-webpacker

原因

そもそもcocooonとjqueryの導入の仕方が変わっていました。

rails5では以下のように実装をした

1.gemのインストール

Gemfile.
gem 'cocoon'
gem 'jquery-rails'

#画像投稿するためにrefileを使用
gem 'refile', require: 'refile/rails', github: 'manfe/refile'
gem 'refile-mini_magick'

2.app/assets/javascripts/application.js

application.js
//= require cocoon
//= require jquery

2.親子関係を結びつける

tour.rb
has_many :tour_photos, dependent: :destroy
accepts_nested_attributes_for :tour_photos, allow_destroy: true

・accepts_nested_attributes_for

一度にまとめてレコードの更新ができるようにできるメソッド。今回の場合だと、Tourレコードを更新すると同時にTourPhotoレコードも一緒に更新できる

・allow_destroy: true

accepts_nested_attributes_forで関連づけられた子レコードを削除できるようにする

tour_photo.rb
belongs_to :tour
attachment :image
validates :image, presence: true

2.フォームを作成

new.html.erb
<%= f.fields_for :tour_photos do |tour_photo| %>
  <%= f.label "写真(5枚選んでください)" %>
  <%= render 'tour_photo_fields', f: tour_photo %>
<% end %>
<div id = "links">
  <%= link_to_add_association '写真を追加',f, :tour_photos %>
</div>
_tour_photo_fields.html.erb
<div class = "nested-fields">
    <%= f.attachment_field :image %>
    <%= link_to_remove_association "写真を削除", f, class: "btn btn-danger remove-photo-btn photo-btn" %>
</div>

以上のようにrails6で同じようにやると、cocoonの追加ボタンが反応してくれなかった

rails6でcocoonを使えるようにするために。

jqueryの導入

yarn add jquery 

・config/webpack/environment.jsの編集

environment.js
const { environment } = require('@rails/webpacker')

#追記ここから
const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)
#追記ここまで

module.exports = environment

cocoonの導入

yarn add github:nathanvda/cocoon#c24ba53

上記のコマンドでpackage.jsonに以下が追加されていれば、導入できている。

package.json
"cocoon": "github:nathanvda/cocoon#c24ba53",

最後にapp/javascriptspacks/application.jsに追記

application.js
require('jquery')
import "cocoon";

まとめ

初めてバージョンの違うrailsを触りましたが、できてたことができなかったりするんですね。
あと、application.jsのファイルの場所が変わっていて、最初は亡くなったのかとビビリ散らかしました。

Rails6でwebpackerが標準になったことにより、Railsアプリの開発環境にyarnのインストールが必要になってるみたいのでお気をつけください。
webpackerとはRailsでモダンなJSフレームワークなどを利用するためのものみたいです。これについても勉強しなければ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

payjpを使って購入機能を実装でい!!

こんにちは。
今日は雨ですね。
偏頭痛持ちの方は気をつけてください。

毎年傘を10本無くす私が言うのは全然説得力が無いと思うのですが、

傘は忘れない様に!!!

さぁ今回はpayjpを使って購入機能を実装するわよ。
(フリマアプリを作成中デスゥ)

payjp導入編もあるので見てない方は先にそちらをチェケラッ

payjp導入編
クレジットカード登録編
ビューなどの補足編

1 まずはルーティングを決めます。

この購入機能をどのコントローラーに入れるかですわねぇ。
色んな記事を読む限り

・商品コントローラーに入れる
・カードコントローラーに入れる
・購入コントローラーを新しく作る

アタイ的には商品テーブルに購入者、購入された時間のカラムを入れているので商品コントローラーの中に入れることにしました。

ですが既存のアクションじゃできないっ!!
なのでこんな感じでルーティングを作りましたわ。

routes.rb
resources :items, only: [:index, :new, :show, :create, :destroy] do
    member do
      get  'purchase'=>  'items#purchase', as: 'purchase'
      patch 'pay'=>   'items#pay', as: 'pay'
      get 'done'=>  'items#done', as: 'done'
    end

なぜmemberにしたかって言うと商品のidが欲しいから。
流れとしては

商品詳細ページ→商品購入ページ→購入アクション→購入完了しましたページ

2 次はコントローラージャイ

商品詳細はいらんからmemberで定義したアクションのみ書いていくわよ!!

items_controller.rb
def purchase
    @item = Item.find(params[:id])
    @card = Card.find_by(user_id: current_user.id)
    if @card == nil
      redirect_to new_card_path
      flash[:noCard] = "Cardが登録されていませんので登録してください"
    else
      Payjp.api_key = Rails.application.credentials[:payjp][:PAYJP_PRIVATE_KEY]
      customer = Payjp::Customer.retrieve(@card.customer_id)
      @card_information = customer.cards.retrieve(@card.card_id)
      # 購入確認ページでカード情報出したいからここで取得。
      # 画像無い人はなくても良いかも。
      @card_brand = @card_information.brand      
      case @card_brand
      when "Visa"
        @card_src = "if-visa-2593666_86609.svg"
      when "JCB"
        @card_src = "jcbcard.png"
      when "MasterCard"
        @card_src = "mastercard.png"
      when "American Express"
        @card_src = "americancard.png"
      when "Diners Club"
        @card_src = "diners_club.png"
      when "Discover"
        @card_src = "discover.png"
      end
      # ---------------------------------------------------------------
    end
  end

  def pay
    @item = Item.find(params[:id])
    card = Card.find_by(user_id: current_user.id)
    Payjp.api_key = Rails.application.credentials[:payjp][:PAYJP_PRIVATE_KEY]
    Payjp::Charge.create(
      amount: @item.price, # Payjpに載る金額
      customer: card.customer_id, # 顧客ID
      currency: 'jpy'
    )
    @item.update(buyer: current_user.id)
    require 'date'
    @item.update(bought_at: Time.now )
  # アタイは購入時間を入れているからここもいらん人はなくてよし
    redirect_to done_item_path(@item.id)
    flash[:notice] = "購入が完了しました"
  end

  def done
  end

こんな感じだわよ。

3 一応ビューファイルも

purchase.html.haml
.purchaseBackground
  = render 'layouts/global-header-simple'

  %main.purchaseMain
    %h2.purchaseMain__content.purchaseTitle 購入内容の確認
    = form_with model: @item, local: true do |f|
      .purchaseMain__content.purchaseItem
        .purchaseItem__imageArea
          = image_tag asset_path('curry.png'), class: 'purchaseItem__imageArea--image', alt: '購入アイテム画像'
        .purchaseItem__box
          %p 
            = @item.name
          .purchaseItem__box--price
            %span 
              = @item.price%span.shipping-fee (税込) 送料込み
      %section.purchaseMain__content
        .purchaseMain__content__wrapper
          .purchaseMain__content__wrapper__price
            .purchaseMain__content__wrapper__price--label 支払い金額
            .purchaseMain__content__wrapper__price--value 
              = @item.price.purchaseMain__content__wrapper
          .purchaseMain__content__wrapper__payMethod
            .purchaseMain__content__wrapper__payMethod--label 支払い方法
            = link_to card_path(@card.id), class: 'changeBtn' do
              変更する
          %p.user-card-info
            クレジットカード
            = "**** **** **** " + @card_information.last4 
          %p.user-card-info
            有効期限
            - exp_month = @card_information.exp_month.to_s
            - exp_year = @card_information.exp_year.to_s.slice(2,3)
            = exp_month + " / " + exp_year
          %figure.user-card-logo
            = image_tag "#{@card_src}",width:'34',height:'20', alt:'master-card'
        .purchaseMain__content__wrapper
          .purchaseMain__content__wrapper__delivery
            .purchaseMain__content__wrapper__delivery--label 配送先
            = link_to '#', class: 'changeBtn' do
              変更する
          %p.user-address-info
        .purchaseMain__content__wrapper
          %p.purchase-info
            郵便局/コンビニ受取をご希望の方は、購入後に<strong>取引画面</strong>から受取場所を変更をすることが可能です。出品者が発送作業を開始した後は受取場所の変更ができませんので、早めに変更を行ってください。
          .btn-enter
            = link_to pay_item_path(@item.id), method: :patch do
              .purchase-btn
                購入する

  = render 'layouts/global-footer-simple'

写真はこんな感じだわよ
スクリーンショット 2020-06-19 16.38.41.png

これでフリマアプリで買い放題だZE!!!

クレジット機能に関してはこんなもんですかね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails]logフォーマットを自分好みに変更する

前提

  • ruby: 2.7.1
  • Rails: 6.0.3

自分好みの Formatter を定義する

config/logger_my_formatter.rb
class Logger
  class MyFormatter < Formatter
    def call(severity, time, progname, msg)
      "[%s#%d] %5s -- %s: %s\n" % [format_datetime(time), $$, severity, progname, msg]
    end
  end
end

自分好みの Formatter を指定する

config/application.rb
require_relative 'boot'
require_relative 'logger_my_formatter' # 追記

# ...

動作確認は production モードで行います(developmentモードはActiveSupport::Logger::SimpleFormatter)。

config/environments/production.rb
Rails.application.configure do
  # ...
  config.log_formatter = ::Logger::MyFormatter.new # 追記
end

動作確認

デフォルト

I, [2020-06-19T16:16:21.592424 #4688]  INFO -- : [e8b5388b-e8d9-4a31-a350-1f3cafdd0dda] Completed 200 OK in 224ms (Views: 102.2ms | ActiveRecord: 40.3ms | Allocations: 65613)

:arrow_down:

変更後

[2020-06-19T16:21:53.497691 #5177]  INFO -- : [d8ef0edd-4d3b-4618-bba7-050a185fa30b] Completed 200 OK in 12ms (Views: 6.3ms | ActiveRecord: 2.5ms | Allocations: 5132)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS☆☆☆ デプロイまでの道のり3(短いバージョン、全5回)

1)背景

第3回目です。自身のポートフォリオをデプロイするために、いよいよunicornを介してrailsを起動します。
AWS関連手順記事はすごく多いので、ここでは備忘録も含めて、非常に端的に手順を記載します。
全5話で進めます。

2)環境

項目 内容
OS.Amazon Linux AMI release 2018.03
Ruby v2.5.1
Ruby On Rails v5.2.4.3
MySQL v5.6
Unicorn v5.4.1

3)内容

以下設定で75分程度かなと思います。(段取りが分かっていれば、30分)
※【ローカルマシン】指定以外は、全てAWSでの作業になります。

(1)【ローカルマシン】Unicornの設定(20分)

  • Gemfileにunicornを記述
  • bundle installの実行(ユニコーン導入)
  • 作成された設定ファイル(unicorn.rb)の編集

(2)Gitのクローニング(15分)

  • 格納フォルダの配置と権限付与
  • Gitからのクローニング(※)
  • AWSのswap領域作成(別記事をご参照ください)

※クローニングする際には以下が必要です。
 (1)先ほどのローカルunicorn設定がpushされていること
 (2)最新master化
 (3)本番環境(production)のDBユーザ設定 

(3)本番デプロイ設定(30分)

  • bundlerのインストール
  • bundle installの実行(時間がかかります。)
  • 秘密鍵の取得
  • 環境変数にdbユーザパスワード(productionと合わせる)と秘密鍵を設定する
  • DB-CreateとDB-Migrateの実行
  • assetsディレクトリのプレコンパイル

(4)本番Rails起動(10分)

  • インスタンスの3000番ポート開放
  • unicornを介してサービスの起動

ここまで完了したら、「http://ElasticIP:3000」にアクセスすると、アプリケーションのトップページに遷移するはずです。

以上、短く記載しました。
ここまで、全てストレートに行ったわけではなく、エラーも出力されました。この辺りは、環境や設定により様々ですので、別記事にてエラー対策を掲載したいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

FinderのデフォルトテキストエディタをAtomに変更する方法

システム環境設定からデフォルトテキストエディタを変更出来なかったのでやり方を調べてみました。

手順

1.Finderから適当なテキストファイルを右クリックし「情報を見る」を選択
2.▼このアプリケーションから設定したいテキストエディタを選択(今回はAtom)
3.その下の「全てを変更」で設定完了

3を飛ばせばファイルごとにエディタを選択できるみたいですね

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【後編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた

はじめに

この記事は、タイトルのとおり、「Everyday Rails」を Rails 6 で勉強したいので、
書籍の翻訳者である伊藤さんのブログを参考にして頑張ってみた記録を記したものである。

記事自体が長くなったので、導入編・前編・中編・後編に分割している。

Rails 6 へのアップグレードは非常に時間がかかるので、いきなり挑戦するのではなく、
まず導入編を読んでいただき、本当に挑戦するのか検討することを強く勧めます。

記録を見たい方は、以下を参照すること。

【導入編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【前編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【中編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita

また、本記事は、伊藤さんのyoutube動画を見ながら作業した内容の実況中継に
近いような形で書き進めているので、以下を必ず併せて視聴してください。
(youtube動画を視聴している前提で書いているので、この記事単体だと意味が通じない)

【前編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)
【後編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)

振り返り

Railsのバージョンを5.2.7までアップグレードした。
続いて、Railsのバージョンを6.0.0に上げていく。

なお、本人はバージョンを6.0.0に上げているつもりだが、指定しきれていないので、
結果として6.0.3.1にバージョンアップされている。

また、この記事は以下の伊藤さんの記事と連動するような形で章立てしている。
その記事内での5番までの作業は不要になるため、次の章は6番からスタートする。

永久保存版!?伊藤さん式・Railsアプリのアップグレード手順 - Qiita

6. Railsを最新のパッチバージョンに上げる

さて、RailsのGemfileを開き、Railsのバージョンを6.00に上げる。
現在では、6.0.3.1が最新版だが、怖いので、とりあえず6.00に上げる。

gem 'rails', '~> 6.0.0'

Gemfileを変更した後、bundle updateを行う。

7. Railsのメジャーバージョン、またはマイナーバージョンを上げる

やらないつもりだったが、しれっとやっているという。。。

8. rails app:updateを実行する

ターミナルでrails app:updateを実行する。

前回と同様に、routes.rbだけ上書きをせず、nと回答する。
そのほかは、yと回答する。

必要に応じて上書きされた設定を元に戻す

Yで上書き実行すると、それまで使っていた重要な設定が失わることがあります。
その場合はgitのdiffをチェックしながら、上書きされて消えてしまった設定を自力で戻していきます。

Rails5.2のバージョンアップの時と同様に対応する。
以下のファイルを変更した。

config/application.rb
 省略 

module Projects
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.

    # 以下が消えていたので、戻した。
    config.generators do |g|
      g.test_framework :rspec,
        view_specs: false,
        helper_specs: false,
        routing_specs: false
    end
  end
end
config/environments/test.rb
# 以下のコードを最後に追加する

# Keep files uploaded in tests from polluting the Rails development
# environment's file uploads
Paperclip::Attachment.default_options[:path] = \
  "#{Rails.root}/spec/test_uploads/:class/:id_partition/:style.:extension"

9. railsdiff.orgを参考にして、新しく追加されたgem等を確認する

次に以下を開き、差分を更新していく。

アプリのことをよく分かっており、かつ勘所がないと困難なので、
伊藤さんの動画の指示に従っていく。

RailsDiff

以下のファイルを変更した。

Gemfile
source 'https://rubygems.org'

git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.1'

gem 'rails', '~> 6.0.0'
gem 'sqlite3', '~> 1.4' # 更新
gem 'puma', '~> 3.11'
gem 'sass-rails', '~> 5' # 更新
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.7' # 更新
gem 'bootsnap', '>= 1.4.2', require: false # 更新

〜 以下省略 〜
config/application.rb
module Projects
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0 # ここを6.0に変更

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.

    config.generators do |g|
      g.test_framework :rspec,
        view_specs: false,
        helper_specs: false,
        routing_specs: false
    end
  end
end

Gemfileを反映させるため、bundle updateを実行する。
無事、成功した。

10. 動作確認を行う

rails cについては、成功した。

rails sについては、動画のとおりrails db:migrateを実行すると、
無事起動することができた。挙動も問題なさそうだった。

bin/rspecを実行し、テストに失敗がないか確認する。
以下のFailuresが発生した。

Failures:

  1) TasksController#show responds with JSON formatted output
     Failure/Error: expect(response).to have_content_type :json
       Expected "unknown content type (application/json; charset=utf-8)" to be Content Type "application/json" (json)
     # ./spec/controllers/tasks_controller_spec.rb:11:in `block (3 levels) in <main>'
     # /Users/kentasuedomi/.rbenv/gems/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:55:in `load'
     # /Users/kentasuedomi/.rbenv/gems/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:55:in `load'
     # /Users/kentasuedomi/.rbenv/gems/2.7.0/gems/spring-commands-rspec-1.0.4/lib/spring/commands/rspec.rb:18:in `call'
     # -e:1:in `<main>'

  2) TasksController#create responds with JSON formatted output
     Failure/Error: expect(response).to have_content_type :json
       Expected "unknown content type (application/json; charset=utf-8)" to be Content Type "application/json" (json)
     # ./spec/controllers/tasks_controller_spec.rb:21:in `block (3 levels) in <main>'
     # /Users/kentasuedomi/.rbenv/gems/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:55:in `load'
     # /Users/kentasuedomi/.rbenv/gems/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:55:in `load'
     # /Users/kentasuedomi/.rbenv/gems/2.7.0/gems/spring-commands-rspec-1.0.4/lib/spring/commands/rspec.rb:18:in `call'
     # -e:1:in `<main>'

Finished in 56.81 seconds (files took 2.96 seconds to load)
70 examples, 2 failures

動画によると、RSpecの書き方が変わったらしい。
expectで始まるコードを修正する。

spec/controllers/tasks_controllers/tasks_controller_spec.rb
require 'rails_helper'

RSpec.describe TasksController, type: :controller do
  include_context "project setup"

  describe "#show" do
    it "responds with JSON formatted output" do
      sign_in user
      get :show, format: :json,
        params: { project_id: project.id, id: task.id }
      expect(response.content_type).to eq "application/json; charset=utf-8" # ここを修正
    end
  end

  describe "#create" do
    it "responds with JSON formatted output" do
      new_task = { name: "New test task" }
      sign_in user
      post :create, format: :json,
        params: { project_id: project.id, task: new_task }
      expect(response.content_type).to eq "application/json; charset=utf-8" # ここを修正
    end

    it "adds a new task to the project" do
      new_task = { name: "New test task" }
      sign_in user
      expect {
        post :create, format: :json,
          params: { project_id: project.id, task: new_task }
      }.to change(project.tasks, :count).by(1)
    end

    it "requires authentication" do
      new_task = { name: "New test task" }
      # Don't sign in this time ...
      expect {
        post :create, format: :json,
          params: { project_id: project.id, task: new_task }
      }.to_not change(project.tasks, :count)
      expect(response.content_type).to eq "application/json; charset=utf-8" # ここを修正
    end
  end
end

bin/rspecを実行し、テストに失敗がないか確認したところ、無事成功した。
ただし、動画同様に警告が出ているので、対応していく。

DEPRECATION WARNING: update_attributes is deprecated and will be removed from Rails 6.1 (please, use update instead) (called from toggle at /Users/HOGE/Desktop/Github作業フォルダ/RSpecPractice/everydayrails-rspec-2017-master/app/controllers/tasks_controller.rb:67)

update_attributesupdateに修正するとのことだった。

ついては、以下のファイルを修正する。

  • app/controllers/tasks_controller.rb
  • app/controllers/projects_controller.rb
  • spec/controllers/projects_controller.rb

さて、次に以下の警告を対応する。

DEPRECATION WARNING: Single arity template handlers are deprecated. Template handlers must
now accept two parameters, the view object and the source for the view object.
Change:
  >> Coffee::Rails::TemplateHandler.call(template)
To:
  >> Coffee::Rails::TemplateHandler.call(template, source)
 (called from <main> at /Users/kentasuedomi/Desktop/Github作業フォルダ/RSpecPractice/everydayrails-rspec-2017-master/Rakefile:6)

動画で紹介されてないのでどうしたものかと思っていたところ、
以下の記事を発見! ありがたい!!!

Rails 6 を動かす際に “DEPRECATION WARNING: Single arity template handlers are deprecated.”
という警告が出た場合の対処 | Lonely Mobiler

結論を読むと、cofee-railsのバージョンが問題らしい。
Gemfileを以下のとおり設定し、bundle updateを行う。

gem 'coffee-rails', '~> 5.0.0'

警告が消えた!
ついに終了!!!

最後に

RSpecの勉強がやっと開始できることを嬉しく思います。
伊藤さん、改めてお世話になります!!!

大変でしたが、こんな初学者がRailsのバージョンアップを
ハンズオンで体験できるという意味ではすごい教材です!!!

ただ、RSpecを純粋に勉強したい人は、バージョンアップするべきかよく考えましょう 笑

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【中編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた

はじめに

この記事は、タイトルのとおり、「Everyday Rails」を Rails 6 で勉強したいので、
書籍の翻訳者である伊藤さんのブログを参考にして頑張ってみた記録を記したものである。

記事自体が長くなったので、導入編・前編・中編・後編に分割している。

Rails 6 へのアップグレードは非常に時間がかかるので、いきなり挑戦するのではなく、
まず導入編を読んでいただき、本当に挑戦するのか検討することを強く勧めます。

記録を見たい方は、以下を参照すること。

【導入編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【前編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【後編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita

また、本記事は、伊藤さんのyoutube動画を見ながら作業した内容の実況中継に
近いような形で書き進めているので、以下を必ず併せて視聴してください。
(youtube動画を視聴している前提で書いているので、この記事単体だと意味が通じない)

【前編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)
【後編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)

4. Rails以外のgemをバージョンアップする

4-c. トラブルが起きやすそうなgemを1つずつアップデートする

RSpecのサンプルアプリでなければ慎重にやるべきなのだが、
動画内で伊藤さんはスルーしていたので、割愛する。

ただ、gemを見つつ、アップデートでトラブルが起きそうでないか確認をしていた。
そういうステップがあるということだけ確認しつつ、次へ進むことにする。

4-d. その他のgemをまとめてアップデートする

伊藤さんによると、次はbundle outdated | bof --format markdown
の実行によって取得できた default と書いてあるgemを見ていくべきとのことだが、
そもそも default と書かれているgemが存在しない。

参考までに、伊藤さんの動画のスクリーンショットと、
私が取得した default と書かれていないgemの一覧を貼付しておく。

勝手な推測だが、伊藤さんが動画を撮った時期と、
私がアップデートしている時期が異なるためだと思われる。
(それか何か余計な操作をしてしまったのかもしれない)

【伊藤さんの動画】
Image from Gyazo

【自分でやってみた結果】

gem newest installed requested groups
actioncable 6.0.3.1 5.1.7
actionmailer 6.0.3.1 5.1.7
actionpack 6.0.3.1 5.1.7
actionview 6.0.3.1 5.1.7
activejob 6.0.3.1 5.1.7
activemodel 6.0.3.1 5.1.7
activerecord 6.0.3.1 5.1.7
activesupport 6.0.3.1 5.1.7
arel 9.0.0 8.0.0
autoprefixer-rails 9.7.6 6.7.7.2
bcrypt 3.1.13 3.1.12
bindex 0.8.1 0.5.0
bootstrap-sass 3.4.1 3.3.7
cocaine 0.6.0 0.5.8
coffee-rails 5.0.0 4.2.1 ~> 4.2
devise 4.7.2 4.4.3
faker 2.12.0 1.7.3
geocoder 1.6.3 1.4.9
i18n 1.8.3 0.9.5
jbuilder 2.10.0 2.6.3 ~> 2.5
jquery-rails 4.4.0 4.3.1
listen 3.2.1 3.1.5 < 3.2, >= 3.0.5
mimemagic 0.3.5 0.3.2
mini_portile2 2.5.0 2.4.0
multi_json 1.14.1 1.12.1
paperclip 6.1.0 5.1.0
puma 4.3.5 3.8.2 ~> 3.7
rails 6.0.3.1 5.1.7 ~> 5.1.1
railties 6.0.3.1 5.1.7
rb-fsevent 0.10.4 0.9.8
rb-inotify 0.10.1 0.9.8
responders 3.0.1 2.4.0
sass 3.7.4 3.4.23
sass-rails 6.0.0 5.0.6 ~> 5.0
spring 2.1.0 2.0.1
sprockets 4.0.2 3.7.2
sqlite3 1.4.2 1.3.13
thor 1.0.1 0.20.3
tilt 2.0.10 2.0.7
turbolinks 5.2.1 5.0.1 ~> 5
turbolinks-source 5.2.0 5.0.0
tzinfo 2.0.2 1.2.7
uglifier 4.2.0 3.2.0
warden 1.2.8 1.2.7
web-console 4.0.3 3.5.0
websocket-driver 0.7.2 0.6.5

この時点でyoutube動画と条件も違うのだが、ここは伊藤さんの動画でやっているとおり、
雑にbundle updateしてみることにする。

けど、正直トラブルになりそうで、とても怖い。。。
とりあえず、後で戻せるようにコミットだけしておく。

やってみると、bundle updateは成功した!
続いて、RSpecでのテストを実行する。

Finished in 25.46 seconds (files took 1.14 seconds to load)
70 examples, 0 failures

無事、成功した!!
ただ、動画で説明のとおり、以下のような警告が出ている。

Sign-ups
DEPRECATION WARNING: [Devise] `DeviseHelper.devise_error_messages!`
is deprecated and it will be removed in the next major version.
To customize the errors styles please run `rails g devise:views` and modify the
`devise/shared/error_messages` partial.

ここで、警告に書かれているとおり、 rails g devise:viewsを実行する。

実行すると、オーバーライトするか尋ねられる。
最初はnとして、次のファイルにてdを押して、差分を確認して以下をコピーする。

-   <%= devise_error_messages! %>
+   <%= render "devise/shared/error_messages", resource: resource %>

他のファイルについては、全てnとする。
コピーした内容を使って、関係ファイルの該当部分を修正する。

<%= devise_error_messages! %>を全て修正する。
修正後は、<%= render "devise/shared/error_messages", resource: resource %>とする。

該当ファイルは以下のとおり。

Image from Gyazo

修正後にRSpecにてテストを行うと、警告が消えた。
bundle outdatedを行うと、以下のとおりとなった。

gem newest installed requested groups
actioncable 6.0.3.1 5.1.7
actionmailer 6.0.3.1 5.1.7
actionpack 6.0.3.1 5.1.7
actionview 6.0.3.1 5.1.7
activejob 6.0.3.1 5.1.7
activemodel 6.0.3.1 5.1.7
activerecord 6.0.3.1 5.1.7
activesupport 6.0.3.1 5.1.7
arel 9.0.0 8.0.0
coffee-rails 5.0.0 4.2.2 ~> 4.2
listen 3.2.1 3.1.5 < 3.2, >= 3.0.5
mini_portile2 2.5.0 2.4.0
puma 4.3.5 3.12.6 ~> 3.7
rails 6.0.3.1 5.1.7 ~> 5.1.1
railties 6.0.3.1 5.1.7
sass-rails 6.0.0 5.0.7 ~> 5.0
sprockets 4.0.2 3.7.2
thor 1.0.1 0.20.3
tzinfo 2.0.2 1.2.7
web-console 4.0.3 3.7.0
websocket-driver 0.7.2 0.6.5

伊藤さんの動画だと、以下のとおりとなっている。

Image from Gyazo

よく見ると違うところもあるが、概ね同じ状態になった。

5. Rubyのバージョンを最新にする

動画での指示に従い、Rubyのバージョンを新しくする。
現在の最新のバージョン(安定版)は2.7.1とのことだが、試すのも怖い。
(動画では2.6.5が採用されている)

とはいえ、伊藤さんによるとRubyは後方互換性を意識しているとのことなので、
commitだけ一応しておいて、バージョン2.7.1で試してみる。

# ruby 2.7.1 をダウンロードする
rbenv install 2.7.1

# rubyのバージョンを 2.7.1 に指定する
rbenv local 2.7.1

# rubyのバージョンが 2.7.1 になっていることを確認する
rbenv version

改めて、bundle installを行う。

すると、gem install bundler 2.1.4を実行せよと指示が出るので、
その指示に従った後、もう一度bundle installを行う。

警告が出るが、i18n, Paperclip, Sassに関連するものであり、
Ruby 2.4.9 を導入してbundleした時の警告と基本的には変わらない。

RSpecでテストを実行する。

Users/HOGE/.rbenv/gems/2.7.0/bundler/gems/shoulda-matchers-4b160bd19ecc/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb:273:in `<class:ValidateInclusionOfMatcher>': undefined method `new' for BigDecimal:Class (NoMethodError)

エラーとなってしまった。

動画上では警告が出るだけだったが、Rubyのバージョンを上げたためなのか、
そもそもRSpecのテストが出来なくなってしまった。

ただ、動画によると、このエラーはRailsのバージョンを上げれば解決するようなので、
Railsを5.2.3にアップデートしてみる。

なお、動画ではGemfileを開き、shoulda-matchersのブランチ指定を解除していたが、
そちらについては後ほど対応することとする。

6. Railsを最新のパッチバージョンに上げる

ここは、実は手順4の中でbundle updateをしている中で済んでいる。

実際のアプリでバージョンアップする場合については、
Railsと他のgemのアップデートはきちんと切り分けた方がよいのかもしれない。

7. Railsのメジャーバージョン、またはマイナーバージョンを上げる

Gemfileを開き、railsのバージョンを以下のとおり設定する。

gem 'rails', '~> 5.2.3'

そして、bundle updateを実行する。
無事、成功した。

8. rails app: update タスクを実行する

終了した後、rails app: updateを実行する。

routes.rbだけはnを押し、それ以外はyを押す。

必要に応じて上書きされた設定を元に戻す

ここで差分を確認しながら、自力で必要な設定を戻していく。
VSCodeを使っていると、以下のとおり確認できる。

Image from Gyazo

動画の指示に従い、設定を以下のとおり戻した。
参考までに記す。

config/application.rb
module Projects
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.1

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.

    # configで始まる部分を追加
    config.generators do |g|
      g.test_framework :rspec,
        view_specs: false,
        helper_specs: false,
        routing_specs: false
    end
  end
end
config/environments/test.rb
# 以下のコードを最後に追加する

# Keep files uploaded in tests from polluting the Rails development
# environment's file uploads
Paperclip::Attachment.default_options[:path] = \
  "#{Rails.root}/spec/test_uploads/:class/:id_partition/:style.:extension"

9. railsdiff.org を参考にして、新しく追加された gem 等を確認する

以下のとおり説明があるので、対応する。

app:updateコマンドを実行しても、Gemfileのようにまったく更新されないファイルもあります。
ですが、rails newした直後のGemfileを比較すると、
デフォルトでインストールされるgemの種類やバージョンには違いがあります。
Railsのバージョンを上げたのであれば、こういった部分も新しいRailsに合わせておく方が安心です。

以下を開き、動画のとおり更新する。
正直、初学者にはどれを更新すべきか、全く見当がつかない。

railsdiff.org

更新した箇所は下記のとおり、3つのファイル。

.gitignore
〜 上部は変更がないので省略 〜

# ---- 以下に修正を加えた ------

# Ignore uploaded files in development # これを追加
/storage/* # これを追加
!/storage/.keep # これを追加

/node_modules
/yarn-error.log

/public/assets # これを追加
.byebug_history

# Ignore master key for decrypting credentials and more. # これを追加
/config/master.key # これを追加

# Ignore uploads from Paperclip
/public/system
/spec/test_uploads

.ruby-version
Gemfile
source 'https://rubygems.org'

git_source(:github) { |repo| "https://github.com/#{repo}.git" } # ここを変更

ruby '2.7.1' # ここを追加

gem 'rails', '~> 5.2.3'
gem 'sqlite3'
gem 'puma', '~> 3.11' # ここを変更
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'bootsnap', '>= 1.1.0', require: false # ここを追加

〜 以下、変更がないので省略します 〜
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>Projects</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

# 以下は変更がないので、省略

さて、変更を終えたので、bundle installを実行する。
実行したところ、無事終了した。

10. 動作確認を行う

動画に従い、rails cを実行する。
すると、rails cの起動は出来たが、以下の警告メッセージが出てきた。

/Users/HOGE/.rbenv/gems/2.7.0/gems/actionpack-5.2.4.3/lib/action_dispatch/middleware/stack.rb:37: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/Users/HOGE/.rbenv/gems/2.7.0/gems/actionpack-5.2.4.3/lib/action_dispatch/middleware/static.rb:111: warning: The called method `initialize' is defined here

また、rails cの挙動を確認したが、エラーとなった。

irb(main):001:0> User.count
Traceback (most recent call last):
        1: from (irb):1
ActiveRecord::StatementInvalid (Could not find table 'users')

動画の中で見逃したのかもしれないが、マイグレーションが必要だったのだろうか。
gittestというブランチを作り、保険だけ掛けておく。

マイグレーションを行うと、無事rails cは動いた。
ただ、動画とは異なり、User.countをしても 21 という数は出てこない。

きっと伊藤さんはテストか何かをしていて、それでUserが21人もいるのだろう。

また、先ほど出てきた警告メッセージは、引き続き出てくる。
気になったので調べてみると、どうやらgemが対応できていないことが原因らしい。

【伊藤さんの個人ブログ】 Ruby 2.7.0 + Rails 6.0.2.1 で警告
warning: Using the last argument as keyword parameters is deprecated を一旦回避 - Just do IT

問題はなさそうなので、とりあえずスルーすることにする。

rails sにてサーバーが立ち上がるかも確認。
無事動き、機能も一通り試したところ問題がなさそうだった。

bin/rspecを実行する。
以下のエラーが出て、テストが実行できなかった。

/Users/HOGE/.rbenv/gems/2.7.0/bundler/gems/shoulda-matchers-4b160bd19ecc/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb:273:in `<class:ValidateInclusionOfMatcher>': undefined method `new' for BigDecimal:Class (NoMethodError)

shoulda-matchersと書いてあるので、ここで放置してきた
shoulda-matchersのブランチ指定を解除を行ってみる。

Gemfileを開き、gem 'shoulda-matchers'以下に書いてある2行のブランチ指定のコードを削除する。
そして、bundle installを実行する。

すると、テストが無事実行できた。

ただ、以下の失敗が起きた。
また、Rubyのバージョンが2.7.1に上がったことが原因だと推測されるが、大量の警告が出た。

Failures:

  1) Notes user uploads an attachment
     Failure/Error: fill_in "Message", with: "My book cover"

     Capybara::ElementNotFound:
       Unable to find field "Message" that is not disabled

〜 省略 〜

  2) Projects user creates a new project
     Failure/Error: fill_in "Name", with: "Test Project"

     Capybara::ElementNotFound:
       Unable to find field "Name" that is not disabled

〜 省略 〜

Finished in 46.59 seconds (files took 3.76 seconds to load)
70 examples, 2 failures

Failed examples:

rspec ./spec/system/notes_spec.rb:11 # Notes user uploads an attachment
rspec ./spec/system/projects_spec.rb:4 # Projects user creates a new project

なお、以下の警告も出てきた。
こちらは動画内で取り上げられていたので、Rubyが2.7.1にバージョンアップしたことが原因ではないもよう。

DEPRECATION WARNING: The success? predicate is deprecated and will be removed in Rails 6.0. Please use successful? as provided by Rack::Response::Helpers. (called from block (3 levels) in <main> at /Users/HOGE/Desktop/Github作業フォルダ/RSpecPractice/everydayrails-rspec-2017-master/spec/controllers/tasks_controller_spec.rb:40)

# 他の箇所にもRSpec関係のファイルにて同様の警告があり

動画に従い、まず以下のFailuresから解決する。

Failures:

  1) Notes user uploads an attachment
     Failure/Error: fill_in "Message", with: "My book cover"

     Capybara::ElementNotFound:
       Unable to find field "Message" that is not disabled

〜 省略 〜

  2) Projects user creates a new project
     Failure/Error: fill_in "Name", with: "Test Project"

     Capybara::ElementNotFound:
       Unable to find field "Name" that is not disabled

これはform_withに関わるエラーであり、HTMLが生成されるときにidが消えてしまうらしい。

config.load_defaultsとnew_framework_defaults_x_x.rbの関係を詳しく調べてみた - Qiita

そこで、以下のファイルを修正する。

config/application.rb
module Projects
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.

    # 5.1から5.2に変更する
    config.load_defaults 5.2

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.

    config.generators do |g|
      g.test_framework :rspec,
        view_specs: false,
        helper_specs: false,
        routing_specs: false
    end
  end
end

RSpecのテストを実行してみると、動画のとおり、全てのテストがパスした。

Finished in 14.12 seconds (files took 1.05 seconds to load)
70 examples, 0 failures

次に、警告を解決する。

改めて英文の警告を確認すると、successsuccessfulに書き換えろと指示があるので、
その指示に従う。すると、警告が消えるらしい。

以下のファイルを開き、指示のとおり対応した。

  • spec/controllers/home_controller_spec.rb
  • spec/controllers/projects_controller_spec.rb
  • spec/controllers/tasks_controller_spec.rb
  • spec/controllers/home_spec.rb

RSpecのテストを実行してみると、警告が消えた。
(もちろん、Ruby2.7.1の導入に起因すると思われる大量の警告は残ったままであるが笑)

これで、Rails5.2へのアップデートが終了した。

どこまで進んだか

動画の後編の12分30秒くらいのところまで進んだ。

【後編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【前編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた

はじめに

この記事は、タイトルのとおり、「Everyday Rails」を Rails 6 で勉強したいので、
書籍の翻訳者である伊藤さんのブログを参考にして頑張ってみた記録を記したものである。

記事自体が長くなったので、導入編・前編・中編・後編に分割している。

Rails 6 へのアップグレードは非常に時間がかかるので、いきなり挑戦するのではなく、
まず導入編を読んでいただき、本当に挑戦するのか検討することを強く勧めます。

導入編・中編・後編については、以下を参照すること。

【導入編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【中編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【後編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita

また、本記事は、伊藤さんのyoutube動画を見ながら作業した内容の実況中継に
近いような形で書き進めているので、以下を必ず併せて視聴してください。
(youtube動画を視聴している前提で書いているので、この記事単体だと意味が通じない)

【前編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)
【後編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)

作業を始める前に

「Everyday Rails - RSpecによるRailsテスト入門」のサンプルアプリについては、
伊藤さんのyoutube動画を見ながら作業すると、以下のとおりアップグレードできる。

変更前の環境 変更後の環境
Rails 5.1.1 6.0.0
rspec-rails 3.8.0 4.0.0.beta2(正式版は3.9.0)
Ruby 2.4.9 2.6.5
その他のgem - できる限り最新化

(2019年10月時点の最新環境)

なお、私は以下のとおりアップグレードした。

なぜと思うところがあるかもしれないが、
初学者なので何となく最新版にしてみたとしか言いようがない。

変更前の環境 変更後の環境
Rails 5.1.1 6.0.3.2
rspec-rails 3.8.0 4.0.1
Ruby 2.4.9 2.7.1
その他のgem - できる限り最新化

(2020年6月18日時点の最新環境・・・と思われる)

あと、初学者なので話半分で聞いてもらいたいが、rubyは2.7.1にしない方がよいような気がする。
様々なgemとの互換性の問題があるためか、警告が大量に出てくる。覚悟して使いましょう。

また、私はヒヨってRailsのバージョンは、6.0.0でよいと思って作業を進めていたが、
gem 'rails', '~> 6.0.0'と書いていたので、結果として最新版に更新できていた。

ブログ内で気になる部分があるかもしれないが、
本人は、Rails 6.0.0 にアップグレードするつもりで頑張っている。

生温かい目で見守ってもらいたい。

伊藤さんのyoutube動画の構成

伊藤さんは、ご自身が書いたRailsアプリのアップグレード手順を参考にして、
順を追ってRSpecのサンプルアプリをアップグレードしている。

以下がそのアップグレード手順を記したQiita記事である。

永久保存版!?伊藤さん式・Railsアプリのアップグレード手順 - Qiita

この記事では、このアップグレード手順に準拠する形で章立てをする。

1. 公式のアップグレードガイドに目を通す

私はほぼ目を通しませんでしたが、通すと勉強になるかと思います。。。

2. テストが全部パスすることを確認する

動画では、テストが全てパスするか確認するよう指示が出ている。
RSpecでのテストは以下のコマンドで実行できる。

bin/rspec

Specテストでいきなりパスしない!

やってみると、下記の記事で紹介されているようなエラーが出た。

Everyday Railsのセットアップにて、masterブランチのテストを全てパスしたい

どうやら、Rubyのバージョンが問題であるようなので、大人しくRubyを2.4.9に指定することにした。
私は、Rbenvを使っているのだが、使い方を忘れているので、以下を参照して対応した。

Rubyのバージョン変更 - Qiita

# ruby 2.4.9 をダウンロードする
rbenv install 2.4.9

# rubyのバージョンを 2.4.9 に指定する
rbenv local 2.4.9

# rubyのバージョンが 2.4.9 になっていることを確認する
rbenv version

無事、Rubyのバージョンを2.4.9に合わせることができた。

また、Specテストにパスしない!

RSpecで再テストすると、以下のとおりエラーが出た。

Failures:

  1) Tasks user toggles a task
     Got 0 failures and 2 other errors:

     1.1) Failure/Error: visit root_path

          Selenium::WebDriver::Error::SessionNotCreatedError:
            session not created: This version of ChromeDriver only supports Chrome version 81

     1.2) Failure/Error: Unable to infer file and line number from backtrace

          Selenium::WebDriver::Error::SessionNotCreatedError:
            session not created: This version of ChromeDriver only supports Chrome version 81

Finished in 27.03 seconds (files took 1.18 seconds to load)
70 examples, 1 failure

Failed examples:

rspec ./spec/system/tasks_spec.rb:12 # Tasks user toggles a task

Pythonの話がベースだが、以下の記事を参考にした。

seleniumで「Message: session not created: This version of ChromeDriver only supports Chrome version 75」のエラーが表示される場合の対処法 - Qiita

どうやら、私が使っているChromeのバージョンとの不一致が問題である可能性が高い。
Chromeのバージョンを確認すると、以下のとおりバージョンが83だった。

Image from Gyazo

エラーメッセージを見直してみると、Everyday Railsの方ではバージョンが81を要求している。

ここでバージョンのダウングレードをしてもよいのだが、
そもそもRailsのバージョンを6にアップグレードした際に、
chromedriver-helperwebdriversに変更するよう指示が出ているので、
ここはスルーすることにする。

3. 開発用ブランチを作成する

ちょくちょくブランチを切りましょう。
保険は大事です。

4. Rails以外のgemをバージョンアップする

さて、指示のとおりブランチを作成した後、Rails以外のgemをバージョンアップする。
なお、一度失敗しているので、ここの記述はかなり冗長である。

4-a. 最新ではないgemを探す(第1チャレンジ)

gemが最新か確認するように指示があるのでbundle outdatedを実行してみる。

outdated gems included in the bundle:
  * actioncable (newest 6.0.3.1, installed 5.1.1)
  * actionmailer (newest 6.0.3.1, installed 5.1.1)
  * actionpack (newest 6.0.3.1, installed 5.1.1)
  * actionview (newest 6.0.3.1, installed 5.1.1)
  * activejob (newest 6.0.3.1, installed 5.1.1)
  * activemodel (newest 6.0.3.1, installed 5.1.1)
  * activerecord (newest 6.0.3.1, installed 5.1.1)
  * activesupport (newest 6.0.3.1, installed 5.1.1)
  * addressable (newest 2.7.0, installed 2.5.2)
  * archive-zip (newest 0.12.0, installed 0.11.0)
  * arel (newest 9.0.0, installed 8.0.0)
  * autoprefixer-rails (newest 9.7.6, installed 6.7.7.2)
  * bcrypt (newest 3.1.13, installed 3.1.12)
  * bindex (newest 0.8.1, installed 0.5.0)
  * bootstrap-sass (newest 3.4.1, installed 3.3.7) in group "default"
  * builder (newest 3.2.4, installed 3.2.3)
  * byebug (newest 11.1.3, installed 9.0.6) in groups "development, test"
  * capybara (newest 3.32.2, installed 2.15.4, requested ~> 2.15.4) in group "test"
  * childprocess (newest 3.0.0, installed 0.8.0)
  * chromedriver-helper (newest 2.1.1, installed 1.2.0) in group "test"
  * cocaine (newest 0.6.0, installed 0.5.8)
  * coffee-rails (newest 5.0.0, installed 4.2.1, requested ~> 4.2) in group "default"
  * concurrent-ruby (newest 1.1.6, installed 1.0.5)
  * crass (newest 1.0.6, installed 1.0.4)
  * devise (newest 4.7.2, installed 4.4.3) in group "default"
  * erubi (newest 1.9.0, installed 1.7.1)
  * factory_bot (newest 5.2.0, installed 4.10.0)
  * factory_bot_rails (newest 5.2.0, installed 4.10.0, requested ~> 4.10.0) in groups "development, test"
  * faker (newest 2.12.0, installed 1.7.3) in group "development"
  * ffi (newest 1.13.1, installed 1.9.18)
  * geocoder (newest 1.6.3, installed 1.4.9) in group "default"
  * globalid (newest 0.4.2, installed 0.4.0)
  * hashdiff (newest 1.0.1, installed 0.3.4)
  * i18n (newest 1.8.3, installed 0.9.5)
  * io-like (newest 0.3.1, installed 0.3.0)
  * jbuilder (newest 2.10.0, installed 2.6.3, requested ~> 2.5) in group "default"
  * jquery-rails (newest 4.4.0, installed 4.3.1) in group "default"
  * launchy (newest 2.5.0, installed 2.4.3, requested ~> 2.4.3) in group "test"
  * listen (newest 3.2.1, installed 3.1.5, requested < 3.2, >= 3.0.5) in group "development"
  * loofah (newest 2.6.0, installed 2.2.2)
  * mail (newest 2.7.1, installed 2.6.5)
  * method_source (newest 1.0.0, installed 0.9.0)
  * mime-types (newest 3.3.1, installed 3.1)
  * mime-types-data (newest 3.2020.0512, installed 3.2016.0521)
  * mimemagic (newest 0.3.5, installed 0.3.2)
  * mini_mime (newest 1.0.2, installed 0.1.4)
  * mini_portile2 (newest 2.5.0, installed 2.3.0)
  * minitest (newest 5.14.1, installed 5.11.3)
  * multi_json (newest 1.14.1, installed 1.12.1)
  * nio4r (newest 2.5.2, installed 2.0.0)
  * nokogiri (newest 1.10.9, installed 1.8.4)
  * paperclip (newest 6.1.0, installed 5.1.0) in group "default"
  * public_suffix (newest 4.0.5, installed 3.0.0)
  * puma (newest 4.3.5, installed 3.8.2, requested ~> 3.7) in group "default"
  * rack (newest 2.2.3, installed 2.0.5)
  * rack-test (newest 1.1.0, installed 0.6.3)
  * rails (newest 6.0.3.1, installed 5.1.1, requested ~> 5.1.1) in group "default"
  * rails-html-sanitizer (newest 1.3.0, installed 1.0.4)
  * railties (newest 6.0.3.1, installed 5.1.1)
  * rake (newest 13.0.1, installed 12.3.1)
  * rb-fsevent (newest 0.10.4, installed 0.9.8)
  * rb-inotify (newest 0.10.1, installed 0.9.8)
  * responders (newest 3.0.1, installed 2.4.0)
  * rspec-core (newest 3.9.2, installed 3.8.0)
  * rspec-expectations (newest 3.9.2, installed 3.8.1)
  * rspec-mocks (newest 3.9.1, installed 3.8.0)
  * rspec-rails (newest 4.0.1, installed 3.8.0, requested ~> 3.8.0) in groups "development, test"
  * rspec-support (newest 3.9.3, installed 3.8.0)
  * rubyzip (newest 2.3.0, installed 1.2.1)
  * safe_yaml (newest 1.0.5, installed 1.0.4)
  * sass (newest 3.7.4, installed 3.4.23)
  * sass-rails (newest 6.0.0, installed 5.0.6, requested ~> 5.0) in group "default"
  * selenium-webdriver (newest 3.142.7, installed 3.6.0) in group "test"
  * spring (newest 2.1.0, installed 2.0.1) in group "development"
  * sprockets (newest 4.0.2, installed 3.7.1)
  * sprockets-rails (newest 3.2.1, installed 3.2.0)
  * sqlite3 (newest 1.4.2, installed 1.3.13) in group "default"
  * thor (newest 1.0.1, installed 0.20.0)
  * tilt (newest 2.0.10, installed 2.0.7)
  * turbolinks (newest 5.2.1, installed 5.0.1, requested ~> 5) in group "default"
  * turbolinks-source (newest 5.2.0, installed 5.0.0)
  * tzinfo (newest 2.0.2, installed 1.2.5)
  * uglifier (newest 4.2.0, installed 3.2.0) in group "default"
  * vcr (newest 6.0.0, installed 3.0.3) in group "test"
  * warden (newest 1.2.8, installed 1.2.7)
  * web-console (newest 4.0.2, installed 3.5.0) in group "development"
  * webmock (newest 3.8.3, installed 3.0.1) in group "test"
  * websocket-driver (newest 0.7.2, installed 0.6.5)
  * websocket-extensions (newest 0.1.5, installed 0.1.2)
  * xpath (newest 3.2.0, installed 2.1.0)

悪夢のような数のgemが。。。

ここで激しい勘違いをしていたのだが、in group developmentin group test
のものをまずアップデートしようと伊藤さんは言っているのであって、
それに該当するのが以下の表になるということらしい。

Image from Gyazo

ちなみに、私はここから明後日の方向に進み出して、最終的に面倒になって、
全てのgemのバージョン指定を解除した後にbundle updateをガツンとしたら、
RSpecで以下のようなエラーが出た。

There is a version mismatch between the Spring client (2.1.0) and the server (2.0.1).

〜  省略 〜

WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated. 
Use Selenium::WebDriver::Chrome::Service#driver_path= instead.

〜  省略 〜

なお、私はこのフェーズにおいて動画をほぼ見ずに作業をしていた。
動画は見ましょう、絶対に。

さて、最初から頑張ってみることにする。

4-a. 最新ではないgemを探す(第2チャレンジ)

ここまでの知見を生かし、Rubyのバージョン指定まで素早くこなす。

そして素直に、Gemfilebundle_outdated_formatterを導入してみる。

指示どおりやっていくと、以下のとおりのエラーが出る。
これは動画でも紹介されているとおりである。

Resolving dependencies...
Bundler could not find compatible versions for gem "bundler":
  In Gemfile:
    rails (~> 5.1.1) was resolved to 5.1.1, which depends on
      bundler (< 2.0, >= 1.3.0)

  Current Bundler version:
    bundler (2.1.4)
This Gemfile requires a different version of Bundler.
Perhaps you need to update Bundler by running `gem install bundler`?

Could not find gem 'bundler (< 2.0, >= 1.3.0)', 
which is required by gem 'rails (~> 5.1.1)', in any of the sources.

ちなみに、これは先ほど試行錯誤していく中でも出たエラーである。

私は、エラーメッセージに従う形でbundlerのバージョンを下げたりして、
ゴニョゴニョやっていったが、伊藤さんによると「bundle update railsならいけるっぽい」
ということなので、ここはこのコマンドを試してみる。

やってみると、上手くアップデートできた。
動画では理屈について少し言及していたが、初学者なのでよく分からず。
ここで調べ出すとキリがなさそうなので、次のステップに行くことにした。

bundle outdated fomatterのコマンドを使って取得した表は、開発環境・テスト環境下で
あるとかそのような状況に関係なく、全てのoutdated gemsを表示する。

そこで、動画の指示のとおり表計算ソフトで加工してみる。
手持ちのlibre officeで加工すると、以下のとおりの表となった。

Image from Gyazo

何やら、伊藤さんのものと比べて、かなりシンプルなものになった。

4-b. development と test グループの gem を先にアップデートする

Gemfileを開き、以下のgemのバージョン指定を外してみる。
外すものは、動画で言及されていたものに限定した。

group :development, :test do
  gem 'rspec-rails' # バージョン指定を解除
  gem 'factory_bot_rails' # バージョン指定を解除
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :test do
  gem 'capybara' # バージョン指定を解除
  gem 'selenium-webdriver' # バージョン指定を解除
  gem 'chromedriver-helper'
  # Or use poltergeist and PhantomJS as an alternative to Selenium/Chrome
  # gem 'poltergeist', '~> 1.15.0'
  gem 'launchy'
  gem 'shoulda-matchers',
    git: 'https://github.com/thoughtbot/shoulda-matchers.git',
    branch: 'rails-5'
  gem 'vcr'
  gem 'webmock'
end

さて、以下を実行する。

bundle update -g development -g test

無事成功した。
ちなみに、動画ではchromedriver-helperからwebdriversに移行するよう指示が出ていた。

サポートが終了したchromedriver-helperからwebdrivers gemに移行する手順 - Qiita

詳細は動画のとおりだが、Gemfile内のchromedriver-helperwebdriversに書き換えて、
bundle installすればよいらしい。私の場合、bundle installは問題なく実行できた。

さて、RSpecで再テストする。
何やら、エラーが色々と出てきた。

[DEPRECATED] `Bundler.with_clean_env` has been deprecated in favor of `Bundler.with_unbundled_env`. 
If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env` (called at /Users/kentasuedomi/.rbenv/gems/2.4.0/gems/spring-2.0.1/lib/spring/application_manager.rb:95)
2020-06-17 18:31:22 WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated. Use Selenium::WebDriver::Chrome::Service#driver_path= instead.
/Users/kentasuedomi/.rbenv/gems/2.4.0/gems/factory_bot-5.2.0/lib/factory_bot/definition_proxy.rb:99:in `method_missing': undefined method 'message' in 'note' factory
Did you mean? 'message { "My important note." }'
 (NoMethodError)

〜 以下、省略 〜

この記事に詳細があるらしい。

【翻訳】factory_bot 4.11で非推奨になった静的属性(static attributes) - Qiita

動画で紹介されているとおり、まず以下を実行する。

gem install rubocop-rspec

そして、以下を実行する。

rubocop \
  --require rubocop-rspec \
  --only FactoryBot/AttributeDefinedStatically \
  --auto-correct

〜 省略 〜

104 files inspected, 10 offenses detected, 10 offenses corrected

RSpecでテストする。
詳細は省略するが、以下の部分だけテストで失敗した。

Failures:

  1) Tasks user toggles a task
     Got 0 failures and 2 other errors:

     1.1) Failure/Error: visit root_path

          VCR::Errors::UnhandledHTTPRequestError:

     1.2) Failure/Error: raise VCR::Errors::UnhandledHTTPRequestError.new(vcr_request)

          VCR::Errors::UnhandledHTTPRequestError:

ただ、このFailuresは動画で紹介されているものである。
詳細は動画で確認してもらいたいが、以下のとおり設定すればテストでの失敗は回避できるらしい。

# spec/support/vcr.rb

VCR.configure do |config|
  config.cassette_library_dir = "#{::Rails.root}/spec/cassettes"
  config.hook_into :webmock
  config.ignore_localhost = true
  # 下記の config.ignore_hosts で始まる1行を追加
  config.ignore_hosts 'chromedriver.storage.googleapis.com'
  config.configure_rspec_metadata!
end

RSpecでテストする。
すると、何と全てのテストが通る!!!

Finished in 9.03 seconds (files took 1.11 seconds to load)
70 examples, 0 failures

どこまで進んだか

動画だと、前編の17分ぐらい経過したところまで進んだ。

続編はこちらは
【中編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【導入編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた

はじめに

この記事は、タイトルのとおり、「Everyday Rails」を Rails 6 で勉強したいので、
書籍の翻訳者である伊藤さんのブログを参考にして頑張ってみた記録を記したものである。

ただ、記事自体が長くなったので、導入編ではその記録を記していない。
Rails 6 で勉強する場合は時間がかかるので覚悟した方がよいという注意喚起のみしか記載していない。

記録を見たい方は、以下を参照すること。

【前編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【中編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita
【後編】「Everyday Rails - RSpecによるRailsテスト入門」を Rails 6 で勉強したいので伊藤さんのブログを参考にして頑張ってみた - Qiita

「Everyday Rails - RSpecによるRailsテスト入門」 とは

Railsを勉強している初学者にとって、RSpecの勉強は避けて通れない道だ。
以下の書籍は、Railsを勉強している初学者の誰もがお世話になるのではないか。

「Everyday Rails - RSpecによるRailsテスト入門」

Everyday Railsは、2017年度にアップデートが行われおり、RSpec3.6やRails 5.1に対応している。
とはいえ、もう2020年度である。

私が6月18日付で調べると、最新版は以下のとおりであった。

  • RSpec 3.9.0 - October 08, 2019
  • RSpec-rails 4.0.1 - May 16, 2020
  • Rails 6.0.3.2 - June 17, 2020

何となく、Rails6系で勉強したいと思う人もいるのではないだろうか。
そう考えていたところ、伊藤さんの記事を発見した。

【動画付き】Everyday RailsのサンプルアプリをRails 6で動かす際に必要なテストコードの変更点 - give IT a try

私は、この記事を見つけて、軽い気持ちで「やってみよー」と思った。
だが、Rails 6でのバージョンアップをやり出したら、相当長くかかった。

幸か不幸か、その過程でメモも取っていたので、それを編集して、
Qiitaという形で公開することにした。

初学者なんだから、こんなブログ書かずに勉強しろという話だが、
もう書きたいという思いが強過ぎるので仕方がない。

Rails 6 で本当にチャレンジする?

伊藤さんのブログでは、以下のとおり記されている。

まとめ(というか結論):Everyday Railsの基本的な内容はほとんど古くなっていません!
というわけで、この記事ではEveryday Railsのサンプルアプリケーションを
Rails 6にアップグレードした際に発生する、テストコード関連の変更点についてまとめました。

Rails 5.1からRails 6にアップグレードするためにはgemのアップデート等、
いろいろな作業が必要になりますが、 テストコードだけに着目すればそれほど大きな変更点はありません。
実際、テストコードで変更する必要があるのはfactory_botの記法と、コントローラスペックの一部だけです。

これはすなわち、Everyday Railsの内容が現在でもほとんど古くなっていないことを意味しています。
ですので、Everyday Railsでテストコードの書き方を学べば、Rails 6環境でも
十分しっかりしたテストを書けるようになるはずです。

これからも安心してEveryday RailsをRSpecの参考書としてご活用ください!

すなわち。

Railsのバージョンを上げないと、factory_botの記法とコントローラスペックの一部だけ古い書き方になるが、
内容にほとんど変更はないからRails5.1で勉強したことが通用する、ということだ。

つまり、Rails5.1でRSpecを勉強することのデメリットはほとんどないということだ。

冷静になって天秤にかけて欲しい。
初学者のみなさん、このデメリット、受け入れちゃってもよいのではないですか。

受け入れたくない方はよく考えていただきたい。
それは、Rails 6 にアップグレードすることのデメリットである。

このデメリットは非常にシンプルで、とにかく時間がかかるということである。

私は、無駄にこのアップグレードの戦いについてノートを取ったり、
よく分からない失敗をしてしまったというのはあるが、作業時間が14時間かかった。

明らかに時間がかかり過ぎであるが、スムーズに進んだとしても6時間はみる必要があると思う。
そもそも伊藤さんのyoutube動画自体が1時間あるのだから、初学者が3時間程度で終わるはずがない。

もちろん、アプリのバージョンアップは現場で必ず行うことなので、
この知見自体は役に立つものである。

ただ、初学者がやるべき優先順位としては低いような気がする。
(それこそ、初学者なのでその判断もつきませんが)

とりあえず、気軽な気持ちで挑戦するのは、絶対に避けましょう!
RSpecを爆速で勉強したい方は、少なくとも現時点においては、Rails5.1で頑張った方がよいです!

それでもやりたい方へ

結論: youtube動画を見て、その動画のとおり作業しましょう!!!

私のように気軽に取り組もうという方は、伊藤さんが提供している以下の情報源に辿り着くはずだ。

【動画付き】Everyday RailsのサンプルアプリをRails 6で動かす際に必要なテストコードの変更点 - give IT a try
【2019年10月版】「Everyday Rails - RSpecによるRailsテスト入門」のセットアップ解説動画を作成しました - give IT a try
【Qiita記事】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順
【前編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)
【後編】永久保存版!?伊藤さん式・Railsアプリのアップグレード手順(youtube動画)

伊藤さんがQiitaに投稿している記事は、あくまでRSpecのテストアプリを事例として扱いつつ、
Railsアプリのアップグレード手順を説明するものなので、
その性質上、細かい手順等はQiita記事内に書かれていない。

私はあまりそのあたりを意識せず、Qiita記事のみを見ながらチャレンジしたので、
色々と失敗に見舞われて、最初からやり直すハメになった。

知識がない人がQiita記事だけの情報でチャレンジすると、色々と勘違いをする可能性や、
Qiita記事に細かく書いていないエラーに対応できない可能性が高いだろう。(私だけですかね 笑)

繰り返しになるが、youtube動画は絶対に見て、その動画のとおり作業しよう!!!

バージョンアップはしない方へ

伊藤さんが環境作成の手順をyoutube動画にして公開している。
参照してみてはどうでしょう?

【2019年10月版】「Everyday Rails - RSpecによるRailsテスト入門」の環境作成手順 - YouTube

補足

「ですます調」だと単調になるので「である調」としましたが、
偉そうに感じられた方、すみません。

あと、私と同じような沼にハマる初学者の方が今後発生するかもしれない
という思いでこの記事を書いていますが、伊藤さんを責める気持ちは全くありません。

チェリー本も大好きです。お世話になってます。
タダにもかかわらず、ブログで積極的に情報発信してくださっているのは非常にありがたいです。

あと、どうでもよいですが、バンド活動をやっていて、
ひょんなきっかけでIT業界に入ってきたにもかかわらず、
今では第一人者として情報発信されているのが不思議で仕方ありません!

いつもありがとうございます!!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む