質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails 7

Ruby on Rails 7は、2021年12月に正式リリースされました。Ruby on Railsのバージョン7であり、フロントエンド開発環境を大幅に刷新。Node.jsを用いない構成がデフォルトになっています。

Q&A

1回答

602閲覧

system_specにて、Couldn't find User with 'id'エラーが出る

.taniyan

総合スコア17

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails 7

Ruby on Rails 7は、2021年12月に正式リリースされました。Ruby on Railsのバージョン7であり、フロントエンド開発環境を大幅に刷新。Node.jsを用いない構成がデフォルトになっています。

0グッド

0クリップ

投稿2022/10/29 07:39

編集2022/10/29 07:59

前提

プロフィール作成フォームにて、user_nameが空欄で入力されたときに、
バリデーションがかかり、「user_nameが空欄の時、登録できないこと」のテストが通るようにしたい
のテストを実装したいがタイトルの通り、Couldn't find User with 'id'エラーが発生しテストが通りません。

実現したいこと

「user_nameが空欄の時、登録できないこと」のテストが通るようにしたい

発生している問題・エラーメッセージ

Failure/Error: expect(user.reload.user_name).to be_invalid ActiveRecord::RecordNotFound: Couldn't find User with 'id'=9 # /usr/local/bundle/gems/activestorage-7.0.4/lib/active_storage/attached/model.rb:237:in `reload' # ./spec/models/user_spec.rb:33:in `block (3 levels) in <main>'

該当のソースコード

user_spec.rb

1require 'rails_helper' 2 3RSpec.describe User, type: :model do 4 describe 'ユーザー登録' do 5 it 'email,passwordが存在すれば登録出来ること' do 6 user = build(:user) 7 expect(user).to be_valid 8 end 9 10 it 'emailが空欄の時、登録できないこと' do 11 user = build(:user) 12 user.email = '' 13 expect(user).to be_invalid 14 end 15 16 it 'passwordが空欄の時、登録できないこと' do 17 user = build(:user) 18 user.password = '' 19 expect(user).to be_invalid 20 end 21 22 end 23 24 describe 'プロフィール登録' do 25 it 'user_nameが存在すれば登録出来ること' do 26 user = build(:user) 27 expect(user).to be_valid 28 end 29 30 it 'user_nameが空欄の時、登録できないこと' do <-----------問題のコード 31 user = build(:user) 32 user.user_name = '' 33 expect(user.reload.user_name).to be_invalid 34 end 35 end 36end

spec/factories/users.rb

1FactoryBot.define do 2 factory :user do 3 sequence(:id) { |n| n} 4 sequence(:email) { |n| "person#{n}@example.com" } 5 password { "123456" } 6 user_name { "test" } 7 self_introduce { "test" } 8 end 9end 10

app/controllers/home_controller.rb

1class HomeController < ApplicationController 2 def top 3 @q = User.ransack(params[:q]) 4 @services = Service.all 5 end 6 7 def profile 8 @user = current_user 9 end 10 11 def update 12 @user = current_user 13 if @user.update(params.permit(:profile_image, :user_name, :self_introduce, :twitter_url, :youtube_url, :instagram_url)) 14 flash[:notice] = "Profile was successfully updated." 15 redirect_to "/" 16 else 17 render 'profile', status: :unprocessable_entity 18 end 19 end 20 21 def show 22 @user = User.find(params[:id]) 23 @user_movies = @user.movies 24 @services = @user.services 25 end 26 27 def search 28 @q = User.ransack(params[:q]) 29 @results = @q.result 30 end 31end 32

app/models/user.rb

1class User < ApplicationRecord 2 # Include default devise modules. Others available are: 3 # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable 4 devise :database_authenticatable, :registerable, 5 :recoverable, :rememberable, :validatable 6 7 has_one_attached :profile_image 8 9 has_many :services, dependent: :destroy 10 has_many :movies, dependent: :destroy 11 12#プロフィール画面でのみバリデーションがかかるように 13 validates :user_name, presence: true, on: :update 14end 15

補足

rails 7
ruby3.1.1

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ほかは
expect(user).to be_valid
なのに、なぜここだけ
expect(user.reload.user_name).to be_invalid
なのですか?
expect(user).to be_invalid
にしてみて。

追記
user.reload.user_name とすれば、UPDATEの時として validateしてくれるか? というのも問題ですが、おかしい所が他にも2点あります。

  1. user.reload は userをもう一度DBから読み込みなおす ということです。

 しかしこの時点では userはDBにはありません。buildしただけで save していませんから。 なので、ActiveRecord::RecordNotFound です
2. user.reload がうまくいったとして、expect(user.reload.user_name).to be_invalid は user が .to be_invalid かどうか、は見ていません。user_name が be_imvalidかどうかを見ています。
つまり、class Nill か class Stringにたいしてみています。 これは エラーになりそうですね

投稿2022/10/29 07:50

編集2022/10/29 10:25
winterboum

総合スコア23331

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

.taniyan

2022/10/29 07:56

ご回答ありがとうございます。 書き忘れておりましたが、userモデルにてupdateメソッドでのみバリデーションがかかるようにしております。 (ユーザーの新規登録時にバリデーションがかかるのを防ぐため。) models/user.rb class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable has_one_attached :profile_image has_many :services, dependent: :destroy has_many :movies, dependent: :destroy validates :user_name, presence: true, on: :update end ですのでupdate時にバリデーションがかかるようにと思い、 expect(user.reload.user_name).to be_invalid とさせていただきました。
winterboum

2022/10/29 08:31

そうすると 「update時にバリデーションがかかる」状態になるのですか?
.taniyan

2022/10/29 08:46

>そうすると 「update時にバリデーションがかかる」状態になるのですか? validates :user_name, presence: true, on: :update はい、これによってプロフィール画面でのupdateメソッドでのみ、バリデーションがかかる状態になっています。
winterboum

2022/10/29 09:42

その validtes の code がUPDATEの時に動く、というのはわかります。 聞きたいのは、user.reload.user_name とすると .to be_invalid が 「これは UPDATEのときだ」と判断してくれる、のですか? という質問です
.taniyan

2022/10/30 02:45

言われてみればおっしゃる通りです。今回のエラーについて新しく質問させていただいたので、よろしければそちらも確認していただけると幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問