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

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

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

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

Ruby

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

1回答

1827閲覧

配列のValuesの取り出し方について

2019

総合スコア9

Ruby on Rails 5

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

Ruby

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

1グッド

1クリップ

投稿2020/02/06 17:56

編集2020/02/07 04:45

問題の概要

railsのコントローラで定義した配列が入っている変数(@times)をViewにて、
配列のValuesのみを取り出そうとすると、
undefined method `[]' for nil:NilClassになり困っております。

該当のコードについて

コントローラで定義した@timesをviewにて、each文で変数timeに代入し、
timeのValuesのみ取り出したい。

<tweets_controller> def index @tweets = Tweet.includes(:user, :tag) @times = Tweet.joins(:tag).group('user_id').group('tag_name').sum(:time) binding.pry ① end ①ここで、binding.pryを行うと、 [1] pry(#<TweetsController>)> @times => {[2, "rails"]=>10}
② <tweets/index.html.haml> - @tweets.zip(@times).each do |tweet,time| = "残り: #{20 - time[1] }h" =>undefined method `[]' for nil:NilClass 検証画面にて、変数の中身を確認。 >> @times => {[2, "rails"]=>10} >> time => nil なぜかnilになっている。。 ・検証画面 スクリーンショット https://gyazo.com/82ccb13c843ca0b8680db5167789bcff
調査内容

確認のため、viewでtime[1]と指定せずに、そのまま変数timeとし、検証を行なった。

③ <tweets/index.html.haml> - @tweets.zip(@times).each do |tweet,time| = "残り: #{20 - time }h" =>Array can't be coerced into Integer 検証画面にて、 >> @times => {[2, "rails"]=>10} >> time => [[2, "rails"], 10] >> time[1] => 10 >> 20 - time[1] => 10 ・検証画面 スクリーンショット https://gyazo.com/d62831eac4450cbd56b44d3ae2ddd8d3

この方法だと、変数timeの中身はnilになっていない。
この違いについて、判断ができず、ご助言いただけないでしょうか。

####エラーコード
②のindex.html.hamlへ遷移した際のターミナルに表示されたエラーコード

Started GET "/tweets" for ::1 at 2020-02-07 02:31:28 +0900 Processing by TweetsController#index as HTML (3.0ms) SELECT SUM(`tweets`.`time`) AS sum_time, `tweets`.`user_id` AS tweets_user_id, tag_name AS tag_name FROM `tweets` INNER JOIN `tags` ON `tags`.`id` = `tweets`.`tag_id` GROUP BY `tweets`.`user_id`, tag_name ↳ app/controllers/tweets_controller.rb:7 Rendering tweets/index.html.haml within layouts/application Tweet Load (10.9ms) SELECT `tweets`.* FROM `tweets` ORDER BY created_at DESC LIMIT 9 OFFSET 0 ↳ app/views/tweets/index.html.haml:8 User Load (5.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 ↳ app/views/tweets/index.html.haml:8 Tag Load (2.5ms) SELECT `tags`.* FROM `tags` WHERE `tags`.`id` IN (3524, 3523, 3522, 3521) ↳ app/views/tweets/index.html.haml:8 User Load (1.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 ORDER BY `users`.`id` ASC LIMIT 1 ↳ app/views/tweets/_tweet.html.haml:9 Rendered tweets/_tweet.html.haml (15.0ms) Rendered tweets/_tweet.html.haml (10.0ms) Rendered tweets/index.html.haml within layouts/application (66.5ms) Completed 500 Internal Server Error in 80ms (ActiveRecord: 22.8ms) NoMethodError - undefined method `[]' for nil:NilClass: app/views/tweets/_tweet.html.haml:22:in `_app_views_tweets__tweet_html_haml__3771684790650645928_70199236271920' app/views/tweets/index.html.haml:9:in `block in _app_views_tweets_index_html_haml__1964772621819836862_70199223973940' app/views/tweets/index.html.haml:8:in `_app_views_tweets_index_html_haml__1964772621819836862_70199223973940' Started POST "/__better_errors/57512c4f5171a4aa/variables" for ::1 at 2020-02-07 02:31:28 +0900

####問題の発生している環境
Mac環境
端末:Macbook Air (2019/13inch)
OS:macOS Catalina(10.15.2)
シェル:zsh
Ruby:2.6.0
Rails:5.2.4

自分のスキルレベル

・HTML/CSS/JavaScript/Ruby/Rails Tutorialレベルは一通り学習済みです。

####追記1
・user : tweet = 1 : 多
・tweet : tag = 多 : 1 (今回は一つのtweetにはtagが一つしかつかない)

usertweettag
columncolumncolumn
user_idtweet_idtag_id
user_idtag_name
tag_id
time

・質問当時のコードのまま、 >> @tweets.zip(@times) で検証を行ないました。

<tweets/index.html.haml> - @tweets.zip(@times).each do |tweet,time| = "残り: #{20 - time[1] }h" =>undefined method `[]' for nil:NilClass 検証画面にて、 >> @tweets.zip(@times) => [[#<Tweet id: 3533, user_id: 2, tag_id: 3528>, [[2, "PHP"], 6]], [#<Tweet id: 3532, user_id: 2, tag_id: 3527>, [[2, "rails"], 7]], [#<Tweet id: 3531, user_id: 2, tag_id: 3526>, nil], [#<Tweet id: 3530, user_id: 2, tag_id: 3525>, nil]] ※created_atなどは記述すると長くなるので、上記では削除してます。

また、ご提案頂いた以下の方法を試しまして、検証画面で>> @tweets.zip(@times)をしましたが、この中身は上記と同じでした。

- @tweets.each do |tweet| - time = @times[tweet.user_id, tweet.tag_name] = "残り: #{20 - time }h" =>undefined method `tag_name' for #<Tweet:0x00007ff0acba3688> Did you mean? tag_id_change https://gyazo.com/715bdb17f0ca021f4523cec77446f4e2
問題に関連している可能性のある箇所

その後、2データ(tweet_id, 3534,3535)追加して>> @tweets.zip(@times)した結果
・登録内容
[
[#<Tweet id: 3535,user_id: 2, tag_id: 3530>, [[2, "PHP"], 6]],
[#<Tweet id: 3534, user_id: 2, tag_id: 3529>, [[2, "rails"], 14]],  ←①
[#<Tweet id: 3533, user_id: 2, tag_id: 3528>, [[2, "経済学"], 4]],
[#<Tweet id: 3532, user_id: 2, tag_id: 3527>, nil],
[#<Tweet id: 3531, user_id: 2, tag_id: 3526>, nil],
[#<Tweet id: 3530, user_id: 2, tag_id: 3525>, nil]
]

< 直接DBに保存されている値を確認 >

Tweet_idtag_idtimetag_name
353035252rails
353135262rails
353235273rails
353335286PHP
353435294経済学
353535307rails

※tag_nameはtagテーブルに保存されてますが、見易さ重視で併記してます。

⇨上記①にある様に、tag_nameが共通しているものは、timeは合計されており、
「2+2+3+7 = 14」になっており、それ以外のデータは**「nil」**になっている。

eachで出力するオブジェクトの中に、nilがいるから出力できないという可能性はありますでしょうか。
ただ、この場合の対処法も分からないのですが、、

また、本データ(tweets)を保存する際に、
accepts_nested_attributes_forを使用して、tagテーブルのカラム(tag_name)を一緒に保存しております。

長文になり、お手数煩わせますが、お気づきの点がございましたら、
教えていただけると幸いです。

以上、恐れ入りますが、よろしくお願い致します。

DrqYuto👍を押しています

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

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

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

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

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

guest

回答1

0

@tweets.zip(@times)を検証してみるとよいでしょう。

おそらく、@tweets.sizeより@times.sizeが小さいです。

haml

1- @tweets.each do |tweet| 2 - time = @times[tweet.user_id, tweet.tag_name] 3 = "残り: #{20 - time }h"

ですかね

投稿2020/02/06 22:04

asm

総合スコア15149

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

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

2019

2020/02/07 04:10

ご返信ありがとうございます! 現状のeach文のままとご提案頂いた方法で動作させて、 検証画面で@tweets.zip(@times)を行いました。 質問文の追記の方に記載しております。 エラーが解消されておりませんが、検証結果で、 一点、気になった点が、 変数@timesの中身の tag_nameですが、tweets_controllerの方で、tag_namedで、 GROUP_BYしておりますので、同一のtag_nameのもので過去データのものが、 「nil」になっておりました。 このせいで、エラーが出ているという事はないでしょうか。 ただ、この対策も思い付かず、お気づきの点がございましたら、 アドバイスいただけると幸いです。 よろしくお願い致します。
asm

2020/02/07 10:09

ようするにzipで単純にくっつけられるデータじゃないんです。 @times[tweet.user_id, tweet.tag.tag_name] なのかな
2019

2020/03/02 16:42 編集

ご返信ありがとございます。 @times[tweet.user_id, tweet.tag.tag_name] でも試しましたが、 以下の様に出力されました。 ``` >> @times => {[2, "PHP"]=>6, [2, "rails"]=>14, [2, "経済学"]=>4, [2, "英語"]=>6, [3, "python"]=>2, [3, "英語"]=>2} ``` そのため、@timesはtweetと別でハッシュとして取り出そうと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問