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

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

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

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

Q&A

解決済

1回答

576閲覧

ポーカー役判定アプリで正しい値を入力した時だけundefined method `+' for nil:NilClassが出る理由は?

koichiro516

総合スコア4

Ruby

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

1グッド

1クリップ

投稿2020/03/03 08:00

編集2020/03/04 03:53

前提・実現したいこと

rails初心者です。
Railsでポーカーの入力した値に対して役を返す判定アプリを作っています。
例えば"S10 S11 S12 S13 S1"と入力すると”ストレートフラッシュ”と返してくれます。
無効な入力をするとメッセージを返すバリデーションは正しく機能するようになりました。
しかし、逆にバリデーションに正しい値を入力すると以下のエラーが発生するようになりました。
"+"に問題があると書いてあるのですが、おかしな箇所が見当たらないため、ご教示いただけませんでしょうか?

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

エラーメッセージ NoMethodError in CardsController#check undefined method `+' for nil:NilClass validate :validate_card_set def validate_card_set if @card_set.blank? errors[:base] << "5つのカード指定文字を半角スペース区切りで入力してください。(例:'S1 H3 D9 C13 S11')" elsif @card_set.match(VALID_REGEX) == nil errors[:base] << " #{ @card_set.split.index(@card_set.split.reject{|r|r.match(/\A[SHDC]([1-9]|1[0-3])\z/)}[0])+1}番目のカード指定文字が不正です。(#{@card_set.split.reject{|r|r.match(/\A[SHDC]([1-9]|1[0-3])\z/)}[0]}) 半角英字大文字のスート(S,H,D,C)と数字(1〜13)の組み合わせでカードを指定してください。" elsif @card_set.split.size > @card_set.split.uniq.size errors[:base] << "カードが重複しています。" end end

該当のソースコード

judge_service.rb

module JudgeService class JudgeCards include ActiveModel::Model attr_accessor :card_set attr_reader :cards, :suits, :numbers, :number_set, :flush, :straight, :hand POKER_HANDS = ["ハイカード", "ワンぺア", "ツーペア", "スリー・オブ・ア・カインド", "ストレート", "フラッシュ", "フルハウス", "フォー・オブ・ア・カインド", "ストレートフラッシュ"] VALID_REGEX = /\A[SHDC]([1-9]|1[0-3]) [SHDC]([1-9]|1[0-3]) [SHDC]([1-9]|1[0-3]) [SHDC]([1-9]|1[0-3]) [SHDC]([1-9]|1[0-3])\z/ validate :validate_card_set def validate_card_set if @card_set.blank? errors[:base] << "5つのカード指定文字を半角スペース区切りで入力してください。(例:'S1 H3 D9 C13 S11')" elsif @card_set.match(VALID_REGEX) == nil errors[:base] << " #{ @card_set.split.index(@card_set.split.reject{|r|r.match(/\A[SHDC]([1-9]|1[0-3])\z/)}[0])+1}番目のカード指定文字が不正です。(#{@card_set.split.reject{|r|r.match(/\A[SHDC]([1-9]|1[0-3])\z/)}[0]}) 半角英字大文字のスート(S,H,D,C)と数字(1〜13)の組み合わせでカードを指定してください。" elsif @card_set.split.size > @card_set.split.uniq.size errors[:base] << "カードが重複しています。" end end def judge_role split_card_set count_same_number flush? straight? judge_hand end def split_card_set() @cards = @card_set.split(" ") @suits = [] @numbers = [] @cards.each do |card| @suits.push card[0] @numbers.push card[1..-1].to_i end end def count_same_number() @number_set = @numbers.group_by{|n|n}.map{|k,v|v.size}.sort.reverse end def straight?() steps = @numbers.sort.map{|n| n - @numbers[0]} if steps == [0,1,2,3,4] || steps == [0,9,10,11,12] @straight = true else @straight = false end end def flush?() suit_set = @suits.uniq.size if suit_set == 1 @flush = true else @flush = false end end def judge_hand() if @straight == true && @flush == true @hand = POKER_HANDS[8] elsif @straight == false && @flush == true @hand = POKER_HANDS[5] elsif @straight == true && @flush == false @hand = POKER_HANDS[4] elsif @number_set == [4,1] @hand = POKER_HANDS[7] elsif @number_set == [3,2] @hand = POKER_HANDS[6] elsif @number_set == [3,1,1] @hand = POKER_HANDS[3] elsif @number_set == [2,2,1] @hand = POKER_HANDS[2] elsif @number_set == [2,1,1,1] @hand = POKER_HANDS[1] else @hand = POKER_HANDS[0] end end end end

cards_controller.rb

class CardsController < ApplicationController include JudgeService def top @card = JudgeCards.new end def check @card = JudgeCards.new(card_set: params[:card_set]) if @card.valid? @card.judge_role render :result else render :error end end def result end def error end end

routes.rb

Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html get '/cards', to: 'cards#top' post 'cards/check', to: 'cards#check' get 'cards/check', to: 'cards#top' get 'cards/result', to: 'cards#result' get 'cards/error', to: 'cards#error' end

試したこと

nilということで、どこがnilを返しているのか探しましたがわかりませんでした。
また、再起動等行いましたが、解決しておりません。

このようなバリデーションが機能しているのに正しい入力の時だけerrorが起きる場合どこがおかしいのでしょうか?

DrqYuto👍を押しています

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

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

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

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

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

guest

回答1

0

自己解決

”undefined method `+' for nil:NilClass”が発生してしまったた原因はnilオブジェクトに対して '+'を用いたからでした。
そのため、要素.to_iとしてnilオブジェクトを0に変換することで解決しました!
nilをintegerに直すと0になるらしいです!

投稿2020/03/04 03:52

koichiro516

総合スコア4

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問