🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

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

Ruby on Rails

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

1回答

736閲覧

RubyOnRailsで掲示板を作成していますがユーザー名が表示できません。

Moi-Moi

総合スコア1

Ruby

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

Ruby on Rails

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2021/01/03 05:34

前提・実現したいこと。

RubyOnRailsで掲示板を作っています。
掲示板(メッセージのindex)に表示させたいのは以下の5つです
①ユーザーID
②ユーザー名(メッセージを投稿した人の名前)
③メッセージのタイトル
⑤メッセージの内容

②を表示させることができません。
(current_userにはできますが、
そうすると当然ですがどのメッセージもログインしているユーザーの名前になってしまいます
今、仮置きで「index.html」に「@user」と記載していますが、画面上は空欄です。
メッセージを投稿した人の名前を表示させたいです)

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

エラーメッセージ
Railsのエラーは以下のものが表示されています。
User must exist

該当のソースコード

RubyOnRails

ソースコード
「messages_controller.rb」
class MessagesController < ApplicationController
before_action :set_message, only: [:show, :edit, :update, :destroy]
before_action :require_user_logged_in, only: [:index, :show,:new,:new,:create, :edit, :update, :destroy ]

def index
@messages = Message.order(id: :desc).page(params[:page])
end

def show
@message = Message.find_by(id: params[:id])
end

def new
@message = Message.new
@message.user_id = current_user.id
@message.save
end

def create
@message = Message.new(message_params)

if @message.save flash[:success] = 'Message が正常に投稿されました' redirect_to @message else flash.now[:danger] = 'Message が投稿されませんでした' render :new end

end

def edit
end

def update

if @message.update(message_params) flash[:success] = 'Message は正常に更新されました' redirect_to @message else flash.now[:danger] = 'Message は更新されませんでした' render :edit end

end

def destroy set_message @message.destroy flash[:success] = 'Message は正常に削除されました' redirect_to messages_url end

private

def set_message @message = Message.find(params[:id]) end

#Strong Parameter
def message_params
params.require(:message).permit(:content, :title)
end
end

「index.html」

<h1>メッセージ一覧 <%= link_to '新規メッセージの投稿', new_message_path, class: "btn btn-primary" %></h1>

<% if @messages.any? %>

<table class="table table-striped"> <thead> <tr> <th>id</th> <th>ユーザー名</th> <th>タイトル</th> <th>メッセージ</th> </tr> </thead> <tbody> <% @messages.each do |message| %> <tr> <td><%= link_to message.id, message %></td> <th><%= @user %></th> <td><%= message.title %></td> <td><%= message.content %></td> </tr> <% end %> </tbody> </table> <div> <%= paginate @messages %> </div> <% end %>

「message.rb」
class Message < ApplicationRecord
belongs_to :user
validates :content, presence: true, length: { maximum: 255 }
validates :title, presence: true, length: { maximum: 255 }
end

試したこと

「index.html」に「@user」と記載している箇所はmessage.user.nameなどと記載しましたが
「undefined method `name' for nil:NilClass」のエラーが表示されました。

補足情報(FW/ツールのバージョンなど)

テーブルは以下のようになっています
describe messages;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| content | varchar(255) | YES | | NULL | |
| user_id | bigint(20) | YES | MUL | NULL | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
| title | varchar(255) | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+

mysql> describe users;
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| email | varchar(255) | YES | | NULL | |
| password_digest | varchar(255) | YES | | NULL | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+

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

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

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

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

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

guest

回答1

0

ベストアンサー

messagesテーブルにuser_idがありますが、とあるメッセージに対してuser_idの値は入っている状態ですか?

また、そのuser_idに対して、usersテーブルにuserが存在する状態ですか?

この2点が満たせていれば、

message.user.name

これでuserの名前が出力されるはずです。

投稿2021/01/03 05:57

educ_gt

総合スコア282

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

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

Moi-Moi

2021/01/03 06:21

今、messagesテーブルを確認したところ、user idが全てnillになっていました。 思い出したのですが、messageテーブルにuser_idのカラムを追加してマイグレーションしたら 「ActiveRecord::StatementInvalid: Mysql2::Error: Duplicate column name 'user_id': ALTER TABLE `messages` ADD `user_id` int」というエラーが出たため、ネットで調べて一旦マイグレーションファイルのuser_idの記載を削除してマイグレーションしたあとにこの記載を戻せはエラーが出なくなる、 というのを見て、そのようにしたままでした。 この時の対応がよくなくて、マイグレーションファイルに誤りがあったのかしら… ちなみにマイグレーションファイルは以下の記載でカラムはmessageテーブルにはuser_idカラムがなかったためマイグレーションで追加しました。 「20201231080655_add_user_id_to_messages.rb」 class AddUserIdToMessages < ActiveRecord::Migration[5.2] def change add_column :messages,:user_id,:integer end end マイグレーションファイルがおかしいでしょうか。
educ_gt

2021/01/03 06:30

user_idカラムへの追加は実際にtableをみた時にuser_idが存在するのであれば、おかしくなさそうです。 user_idのカラムの空の部分には実在するユーザーのidを手動でも構わないので入れ込んでください。 そしたら出力がうまくいくと思います。
Moi-Moi

2021/01/03 06:50

ありがとうございます! 一旦DBのデータをカラにしてからseedファイルでuser_idがあるデータだけにしたところ、 画面のユーザー名のところに名前が表示されました!! ですが、マイグレーションファイルのせいか、 画面からメッセージを投稿しても「User must exist」と表示され、投稿ができなくなっています。 マイグレーションしなおすにも、一度user_idを追加したことになっているようなので、 どのように扱えば良いかわからずです…
educ_gt

2021/01/03 07:02

よかったです! ``` 画面からメッセージを投稿しても「User must exist」 ``` これは、belongs_to: user によって設定されるvalidationが働いている状態ですね。 つまり、belongs_toによってuserが存在しないメッセージを保存できないような状態になっているということです。 def message_params params.require(:message).permit(:content, :title) end このストロングパラメーターの箇所にuser_idが存在しないですよね? ストロングパラメータにmergeで入れる、がよさそうです。 deviseをつかっていて、loginしているユーザーしか投稿出来ないようにしているのであれば、mergeでcurrent_userのid情報をuser_idとしてストロングパラメータに紐づけてやればよさそうです。
Moi-Moi

2021/01/03 07:22

重ね重ねありがとうございます! # Strong Parameter def message_params params.require(:message).permit(:content, :title).merge(user_id: current_user.id) end このように記載したところ、見事に投稿ができるようになりました! 新春早々、ご親切に教えていただき心が弾みました。 私もいずれ困っている人に教えてあげられるようにスキルアップします! ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問