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

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

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

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

Q&A

1回答

14943閲覧

UrlGenerationErrorを解決できません。

begin1990

総合スコア31

Ruby on Rails

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

0グッド

2クリップ

投稿2018/01/18 13:26

編集2022/01/12 10:55

現在、UrlGenerationError in Toppages#indexが発生しています。

詳しく書くと、「No route matches {:action=>"create", :controller=>"comments", :post_id=>nil} missing required keys: [:post_id]」です。

恐らく、postのidが渡っていないためエラーが起きていると考えられます。

現在のコードは以下の通りです。

ビュー部分

<% if current_user %> <%= form_tag(post_comments_path(@post.id), method: :post) do %> <textarea cols="30" name="text" placeholder="コメントする" rows="2"></textarea> <br/> <input type="submit" value="コメントの投稿"> <% end %> <% end %>

コメントコントローラー

class CommentsController < ApplicationController before_action :set_comment, only: [:new,:create, :destroy] before_action :require_user_logged_in def create @post = Post.find(params[:post_id]) @comment = @post.comments.new(comment_params) @comment.user_id = current_user.id #@comment = current_user.posts.comments.build(comment_params) #@comment = Comment.create(text: comment_params[:text], post_id: comment_params[:post_id], user_id: current_user.id) if @comment.save flash[:success] = "コメントしました。" #redirect_to "/posts/#{@comment.post.id}" #redirect_to post_comments_path(@post.id) #redirect_to :action =>"new" redirect_back(fallback_location: root_path) else render 'toppages/index' end end def destroy @comment.destroy flash[:success] = 'コメントを削除しました。' redirect_back(fallback_location: root_path) end private # Use callbacks to share common setup or constraints between actions. def set_comment @post = Post.find(params[:post_id]) @comment = @post.comments.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def comment_params params.require(:comment).permit(:user_id, :post_id, :content) end end

ルーティング

Rails.application.routes.draw do root to: 'toppages#index' get 'login', to: 'sessions#new' post 'login', to: 'sessions#create' delete 'logout', to: 'sessions#destroy' resources :users do member do get :followings get :followers end collection do get :search end end resources :posts, only: [:create, :destroy, :show] , shallow: true do resources :comments, only: [:create, :destroy] end resources :relationships, only: [:create, :destroy] get 'signup', to: 'users#new' end

トップページのcontroller

class ToppagesController < ApplicationController def index if logged_in? @user = current_user @post = current_user.posts.build # form_for 用 @posts = current_user.feed_posts.order('created_at DESC').page(params[:page]) end end end

ビュー部分を、<%= link_to "コメントを投稿", method: :post, :action =>"create", :controller =>"comments", :post_id =>nil, class: 'btn btn-danger btn-sm' %>や、<%= form_tag(post_comments_path(@post.id), :action =>"create", :controller =>"comments", :post_id =>nil, method: :post) do %>としてみたり、コントローラーのコメントアウト部分を一時有効にしてみたり、ググったりしてみましたが、中々解決できませんでした。

どなたかわかる方、ご教示お願い申し上げます。

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

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

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

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

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

scivola

2018/01/18 15:15

Comment を create するための(create アクションを起こすための)ビューでエラーが出ているのですよね。であれば create アクションじゃなくて new アクションのコードを見なければなりません。追記していただけますか。
begin1990

2018/01/18 15:25

newアクションは全く作っていないので、これから作ります。
scivola

2018/01/18 15:37

え? では,どんな URL でアクセスしたとき,コードのどこでエラーが出たのですか。
begin1990

2018/01/19 00:27

scivolaさん、連絡遅くなってすみません。これから仕事ですので、返信は恐らく今夜になる予定です。よろしくお願いします。
begin1990

2018/01/19 11:21 編集

scivolaさん、大変お待たせ致しました。現在は、```<%= form_tag(post_comments_path(@post.id), method: :post) do %>```の行で、https://gyazo.com/cee7eaba2c670e2845d38f3a91ad15fa というエラーが発生しています。 ちなみに、これはトップページにアクセスしたときに発生しています。
scivola

2018/01/20 04:37

ToppagesController の index アクションでエラーが起こっているので,そのアクションの定義を見せてください
begin1990

2018/01/20 04:40

トップページのcontrollerを追加しました。
guest

回答1

0

ToppagesControllerindex において,

rb

1@post = current_user.posts.build

としてますよね。
これで @post には Post オブジェクトが入るわけですが,この Post オブジェクトはデータベースにはまだ記録されていません。したがって,id カラムの値は nil です。

しかるに,ビューにおいて

rb

1post_comments_path(@post.id)

で URL を作ろうとしています。
@post.idnil ですから,URL が作れません。
それが

No route matches {:action=>"create", :controller=>"comments", :post_id=>nil}

というエラーの意味するところです。

このフォームは何のためにあるかというと,投稿(Post)に対してコメントを付ける(Comment を作る)ためですよね。
であれば特定の(すでにデータベースに入っている)Post を持ってこなければなりません。
だからコントローラーで

rb

1@post = current_user.posts.build

として Post オブジェクトを作成するのはおかしいんです。

投稿2018/01/20 06:14

scivola

総合スコア2108

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

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

begin1990

2018/01/20 07:56 編集

ご回答ありがとうございます。 だから、@post.idがnilになるわけですね。 ということは、特定のPostを、トップページのcontrollerに持ってくる必要があるということですよね? けれど、@post = current_user.posts.buildはpost投稿に欠かせないので、どう変えれば良いのかわかりません。
scivola

2018/01/20 08:44

そのコメントはどの Post に対するコメントですか。
begin1990

2018/01/20 10:13 編集

既に、データベースに記録されたPostです。 それと、@post = current_user.posts.buildをどう変えるかわからないのが今の現状です。
scivola

2018/01/20 10:27

その「データベースに記録されたPost」というのは, current_user とは関係ありますか。あるとすればどういう関係ですか。
scivola

2018/01/20 22:19

やりたいことは,トップページに Post 一覧を表示し,そのそれぞれの Post にコメント投稿欄を用意し,といったことでしょうか?
begin1990

2018/01/21 01:30

そうです。その通りです。
scivola

2018/01/21 08:32

で,その Post 一覧に表示すべき Post たちは @posts に入っているわけですね? ビューが一部しか掲出されていないのでよく分かりませんが,ビューの中で @posts.each do |post| みたいなループがあるわけですよね? で,そのループのなかにコメント用のフォームがあればいいんですよね。 そして,そのフォームを生成するヘルパーは form_tag(post_comments_path(@post.id), method: :post) じゃなくて form_tag(post_comments_path(post.id), method: :post) なのではありませんか。
begin1990

2018/01/21 09:04

ご回答ありがとうございます。 おっしゃる通り、ビューの中で @posts.each do |post| みたいなループがあり、そのループのなかにコメント用のフォームがあれば良いのです。 form_tag(post_comments_path(post.id), method: :post)に修正した所、UrlGenerationError in Toppages#indexは無くなりましたが、今度は別のエラーが発生しました。 https://gyazo.com/7aee6998437a99d0075840677d544aca コメントコントローラも、一部ではなく全て貼り付けました。 これ以上長くなりそうなので、別件で質問した方が良いでしょうか?
scivola

2018/01/21 21:12

set_comment というのは既存の Comment オブジェクトを @comment にだいにゅうするためのものですよね。 でも before_action :set_comment, only: [:new,:create, :destroy] となっっています。 new や create する段階ではまだデータベースに入ってないので,set_comment するのはおかしいですね。
begin1990

2018/01/22 03:55

ご回答ありがとうございました。 before〜という部分は削除した方がいいですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問