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

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

ただいまの
回答率

90.13%

(NameError)uninitialized constant Post::UserIdの解決方法について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 689

ayachika

score 34

こんにちは。いつもお世話になっております。

今回表記のエラーについてお知恵をお借りしたいと考えております。

現在、投稿サイト(twitterのような)を作成しており、ユーザーと投稿の紐づけを行っているところです。user_idとpostの紐付けを行おうとしています。

belongs_toやhas_manyの記述は行ったのですが、以下のようなエラーが出てしまいます。

NameError in PostsController#create
uninitialized constant Post::UserId
Extracted source (around line #20):

18     def create
19         # Post モデルを引数のパラメータで初期化(データの保存は指定ない)
20        post = Post.new(
21            content: params[:content],
22            user_id: @current_user.id
23            )

20のところが赤い行になっています。
投稿ボタンを押すとこのようなエラーがでます。Post::UserIdが定義されていないよというエラーだと思うのですがどこに定義すればいいのか、わかりません。
また、このような形の定義が出てくる理由がわかりません。

事前にネットで調べたりしらのですが、インターネット上での解決方法を試してみてもエラーが解決しなかったため、質問させていただきます。
よろしくお願いします。
以下、参考です。

ユーザーモデル

# == Schema Information
#
# Table name: users
#
#  id              :integer          not null, primary key
#  email           :string
#  name            :string
#  password_digest :string
#  remember_digest :string
#  created_at      :datetime         not null
#  updated_at      :datetime         not null
#  user_id         :integer
#
# Indexes
#
#  index_users_on_email  (email) UNIQUE
#

class User < ApplicationRecord

    has_many :favorites, through: :favorites, source: :post, dependent: :destroy
    has_many :posts, through: :favorites, dependent: :destroy ,foreign_key: 'user'

    before_save { email.downcase! }
    validates :name,  presence: true, length: { maximum: 50 }
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
    validates :email, presence: true, length: { maximum: 255 },
                            format: { with: VALID_EMAIL_REGEX },
                            uniqueness: { case_sensitive: false }
    has_secure_password
    validates :password, presence: true, length: { minimum: 6 }

    # 渡された文字列のハッシュ値を返す
  def self.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

# ランダムなトークンを返す
  def self.new_token
    SecureRandom.urlsafe_base64
  end

# 永続セッションのためにユーザーをデータベースに記憶する
  def remember
    self.remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
  end

# 渡されたトークンがダイジェストと一致したらtrueを返す
  def authenticated?(remember_token)
    return false if remember_digest.nil?
    BCrypt::Password.new(remember_digest).is_password?(remember_token)
  end

  # ユーザーのログイン情報を破棄する
  def forget
    update_attribute(:remember_digest, nil)
  end



end

postモデル

#  picture    :string
#  title      :string
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class Post < ApplicationRecord
    #Commentモデルを複数持てる様にする
    has_many :posts, dependent: :destroy
    has_many :comments, dependent: :delete_all
    has_many :post_tag_relations, dependent: :delete_all # 追加
    has_many :tags, through: :post_tag_relations  #追加
    belongs_to :user_id
    validates :user_id, presence: true
    default_scope -> { order(created_at: :desc) }
    # presence -> 必須チェック
    # length -> 文字数の制限
   # validates :name, presence: true, length: { maximum: 30 }
    validates :title, presence: true, length: { maximum: 30 }
    validates :content, presence: true, length: { maximum: 1000 }

    #画像のアップロード機能を持たせる
    mount_uploader :picture, PictureUploader
    validates :user, presence:true

    #favoriteモデル追加
    has_many :favorites, dependent: :destroy
    has_many :users, through: :favorites
    validates :user_id,presence: true
    validates :content, presence: true, length: { maximum: 140 }

end

users_controller.rb

class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
    @user = User.find(params[:id])

    # モデルクラスのwhereメソッドへ検索カラムと値を渡すと合致するモデルを配列形式で返却
    #@posts = Post.where(:user_id, @user.id)
  end

  def new
    @user = User.new
  end

  def create

    @user = User.new(user_params)   
    if @user.save
      log_in @user
      # 保存の成功をここで扱う。
      flash[:success] = "Tsukutta!へようこそ"
      redirect_to @user
    else
      flash[:error_messages] = @user.errors.full_messages
      render 'new'
    end
  end

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end

end

posts_controller.rb

# Applicationcontrollerクラスを継承することで、クラスがコントローラと認識される
class PostsController < ApplicationController
    def index
        # 追加
        # タグが選択されている場合は、タグに関連されているデータを取得、そうでなければ全てのデータを取得(ただし、データの全検索はしてない)
        @posts = params[:tag_id].present? ? Tag.find(params[:tag_id]).posts : Post.all

        # page メソッドを呼ぶと引数に指定したページに表示するデータ分だけ取得(デフォルトは、25件)
        @posts = Post.page(params[:page])

    end

    #ルーティングの変更後に追加
    def new
        @post = Post.new(flash[:board])
    end

     def create
         # Post モデルを引数のパラメータで初期化(データの保存は指定ない)
        post = Post.new(
            content: params[:content],
            user_id: @current_user.id
            )

        # 保存の正否をチェック
   if post.save
      # フラッシュ
      flash[:notice] = "「#{post.title}」の記事が投稿されました!"
      redirect_to post
    else
    redirect_to new_post_path, flash: {
      post: post,
      error_messages: post.errors.full_messages
    }
   end
     end


    # findメソッドで、idにひもづくPOSTオブジェクトを取得する
    def show
     @post = Post.find(params[:id])
     # @comment = @post.comments.new
    @comment = Comment.new(post_id: @post.id)
    end

    # 追加
    def edit
        @post = Post.find(params[:id])
    end

    def update
        post = Post.find(params[:id])
        # モデルの更新は、クラスメソッドのupdateメソッドで行える
        post.update(post_params)

        # フラッシュ
        flash[:notice] = "「#{@post.title}」の記事を更新しました!"

        # リダイレクト処理
        redirect_to @post
    end

    # 削除機能
    def destroy

        @post = Post.destroy(params[:id])

         # フラッシュ 
        flash[:notice] = "「#{@post.title}」の記事を削除しました!"

        # 投稿一覧へリダイレクト
        redirect_to posts_path
    end

    private

    #paramsから欲しいデータのみ抽出
    def post_params
        #params.require(:post).permit(:name, :title, :content)
        # tag_ids をリストで追加 #tagがうまくいかない
        params.require(:post).permit(:user_id,:name, :title, :content, :picture, :tag_ids)


    end

    def set_target_post
        @post = Post.find(params[:id])
    end

end

ちなみに参考にしているサイトはrailsでユーザーと投稿を紐付けるです。
これをもとに、application_controller_rbはこのようになっています。

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper

  before_action :set_current_user

  def set_current_user
    @current_user = User.find_by(id: session[:user_id])
  end
end
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

postsテーブルがuser_idカラムを持っていません。
代わりにusersテーブルがuser_idカラムを持ってしまっているみたいです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/05 10:55

    railsも再起動しています…原因がわからずすみません(´;ω;`)

    キャンセル

  • 2018/11/05 11:02 編集

    もしかしてここですかね...
    # models/post.rb
    belongs_to :user_id
    ここは
    belongs_to :user
    が正しいと思われます。どうでしょうか...

    キャンセル

  • 2018/11/05 11:10

    ありがとうございます!解決できました!少し質問の内容がずれてしまいましたがそれにもお答えいただきありがとうございました!

    キャンセル

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

  • ただいまの回答率 90.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる