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

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

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

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

Ruby on Rails

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

Q&A

解決済

1回答

730閲覧

railsでコメントモデル、投稿モデル、ユーザーモデルリレーションを組んだがcomment.user.nameがnilエラー

railsganbaruman

総合スコア16

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2020/07/18 12:48

編集2020/07/19 06:22

【Rails】コメント機能の実装を参考にコメント機能を実装しました。コメント機能は期待通り動いています。
ただ、コメントの表示でコメントした人の名前を呼び出したい時
comment.user.name
とするとnameがnilエラーをはきます。
Userモデルにnameカラムがあることを確認しております。
不明点は
comment.tweet.user.name
とするとエラーはなく名前を呼び出せることです。
原因を教えていただきたいです。
show.html.erb

<p id="notice"><%= notice %></p> <p> <strong>Context:</strong> <%= @tweet.context %> </p> <%= link_to 'Edit', edit_tweet_path(@tweet) %> | <%= link_to 'Back', tweets_path %><br> <h2>comments</h2> <% @comments.each do |comment| %> <%= attachment_image_tag comment.user, :profile_image, :fill, 50, 50, size:'50x50', fallback: "no_image.jpeg", class: "rounded-circle" %> <%= comment.tweet.user.name %> <!------この行です------> <%= comment.content %> <br> <% end %> <h2>reply</h2> <%= form_for([@tweet,@comment]) do |f| %> <%= f.text_area :content %> <%= f.submit %> <% end %>

comments_controller.rb

class CommentsController < ApplicationController before_action :authenticate_user! def create tweet = Tweet.find(params[:tweet_id]) @comment = tweet.comments.build(comment_params) @comment.tweet_id = tweet.id @comment.user_id = current_user.id if @comment.save redirect_back(fallback_location: root_path) else redirect_back(fallback_location: root_path) end end private def comment_params params.require(:comment).permit(:content) end end

tweets_controller.rb (中略)

def show @tweet = Tweet.find(params[:id]) @comments = @tweet.comments @comment = @tweet.comments.build end

tweet.rb

ruby

1class Tweet < ApplicationRecord 2 belongs_to :user, dependent: :destroy, optional: true 3 has_many :comments, dependent: :destroy 4end

user.rb

ruby

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 validates :name, presence: true 8 validates :introduction, length: { maximum: 200 } 9 10 has_many :tweets, dependent: :destroy 11 has_many :comments, dependent: :destroy 12 13 attachment :profile_image 14end

comment.rb

class Comment < ApplicationRecord belongs_to :user belongs_to :tweet end

schema.rb

# This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # # This file is the source Rails uses to define your schema when running `rails # db:schema:load`. When creating a new database, `rails db:schema:load` tends to # be faster and is potentially less error prone than running all of your # migrations from scratch. Old migrations may fail to apply correctly if those # migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. ActiveRecord::Schema.define(version: 2020_07_18_091312) do create_table "comments", force: :cascade do |t| t.text "content" t.integer "user_id", null: false t.integer "tweet_id", null: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["tweet_id"], name: "index_comments_on_tweet_id" t.index ["user_id"], name: "index_comments_on_user_id" end create_table "tweets", force: :cascade do |t| t.text "context" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.integer "user_id" end create_table "users", force: :cascade do |t| t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.string "name" t.text "introduction" t.string "profile_image_id" t.index ["email"], name: "index_users_on_email", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end add_foreign_key "comments", "tweets" add_foreign_key "comments", "users" end

検討に必要なファイルがありましたらコメントください。

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

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

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

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

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

gouf

2020/07/18 13:08

db/schema.rb の内容を質問欄に追記可能ですか?
railsganbaruman

2020/07/19 06:22

コメントありがとうございます。追記しました。
guest

回答1

0

ベストアンサー

この時期のRailsでの質問ですから、「rails5またはrais6であり、rails4より古いことは無い」前提で答えます。
comment.user.name が nameがnilエラーをはきます ということは

1: comment.user_id が nil
2: comment.user_id はあるが、そのidをもつUserが居ない

で、rails5またはrais6で
class Comment < ApplicationRecord belongs_to :user
とあると、この 1,2は起こりえません。commentのsaveの時にvalidationエラーとなってsaveできませんから。
また commentにuser_idカラムがない場合もエラーとなります。

とすると可能性あるのは
そのcommentは、class Commentにbelongs_to :userを設定する前に作られたものである。
確かめ方はいくつか、
0. そういやそうだ、と自覚がある

  1. rails c して そのcommentを取り出し、user_idを確認する

  Comment.find(そのid).user_id
2. 新たにcommentを作成し、その comment.user.name を参照してみる

投稿2020/07/18 23:21

winterboum

総合スコア23567

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

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

railsganbaruman

2020/07/23 01:11

回答ありがとうございます。 3.の確かめかたを確認すると参照できました。 「そのcommentは、class Commentにbelongs_to :userを設定する前に作られたものである。」 これだったみたいです。 勉強になりました!また機会があればよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問