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

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

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

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

Q&A

1回答

9096閲覧

ParameterMissingを解決できません

begin1990

総合スコア31

Ruby on Rails

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

0グッド

0クリップ

投稿2018/01/22 12:37

編集2018/01/26 12:31

現在、「param is missing or the value is empty: comment」というエラーが、CommentsController#createで発生しています。

http://original-app-takasakifuse.c9users.io:8080/posts/5/comments

コードは以下の通りです。
toppage_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]) @comment = @post.comments.build @comments = @post.comments.order('created_at DESC').page(params[:page]) end end end

comment_controller

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.create(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 @comments = @comments.order('created_at DESC').page(params[:page]) flash.now[:danger] = 'コメントの投稿に失敗しました。 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

user_controller

class UsersController < ApplicationController before_action :require_user_logged_in, only: [:index, :show, :edit, :destroy, :followings, :followers] def index @users = User.all.page(params[:page]) end def show @user = User.find(params[:id]) @posts = @user.posts.order('created_at DESC').page(params[:page]) @comment = Comment.create(user_id: @user.id) @comments = @posts.comments counts(@user) end def new @user = User.new end def create @user = User.new(user_params) if @user.save flash[:success] = 'ユーザを登録しました。' redirect_to @user else flash.now[:danger] = 'ユーザの登録に失敗しました。' render :new end end def edit @user = User.find(params[:id]) render :edit end def update @user = User.find(params[:id]) if @user.update_attributes(user_params) redirect_to @user flash[:success] = "プロフィールを更新しました" else flash.now[:danger] = 'プロフィールを更新できませんでした。' render'edit' end end def destroy @user = User.find(params[:id]) @user.destroy flash[:success] = 'ユーザー登録を解除しました。' redirect_back(fallback_location: root_url) end def followings @user = User.find(params[:id]) @followings = @user.followings.page(params[:page]) counts(@user) end def followers @user = User.find(params[:id]) @followers = @user.followers.page(params[:page]) counts(@user) end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation, :introduction, :address, :age) end end

posts_html.erb

<ul class="media-list"> <% posts.each do |post| %> <% user = post.user %> <li class="media"> <div class="media-left"> <img class="media-object img-rounded" src="<%= gravatar_url(user, options = { size: 50 }) %>" alt=""> </div> <div class="media-body"> <div> <%= link_to user.name, user_path(user) %> <span class="text-muted">posted at <%= post.created_at %></span> </div> <div> <p><%= image_tag post.picture,:size =>"280x210" %></p> <p><%= post.content %></p> <% if @comments %> <% @comments.each do |comment| %> <div class="name2">投稿者:<%= link_to comment.user.username, "/users/#{comment.user_id}" %>&nbsp;&nbsp;投稿日時:<%= comment.created_at.strftime("%Y-%m-%d %H:%M:%S") %></div> <div class="name2"><%= comment.text %></div> <% end %> <% end %> <br/> <% 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 %> </div> <div> <% if current_user == post.user %> <%= link_to "削除", post, method: :delete, data: { confirm: "本当に削除してよろしいですか?" }, class: 'btn btn-danger btn-sm' %> <% end %> </div> </div> </li> <% end %> <%= paginate posts %> </ul>

コメントのマイグレーションファイル

class CreateComments < ActiveRecord::Migration[5.0] def change create_table :comments do |t| t.references :user, foreign_key: true t.references :post, foreign_key: true t.string :content t.timestamps end end end

コメントのモデル

class Comment < ApplicationRecord belongs_to :user belongs_to :post end

ルーティング
routes.rb

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

/posts を表示したときのコメントのフォームの <form> タグの部分(ブラウザーで HTML ソースを表示してその HTML 断片)

<form class="new_comment" id="new_comment" action="/posts/5/comments" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><input type="hidden" name="authenticity_token" value="4i0OQgfiY2xoD/pIvEJI9XtKhTfJnyjRfZAVOVJ9i9wvQSHu/zWiXB7b6HA35FG0AdkwxgS4AgM2jPEkA+r+Ug==" /> <textarea cols="30" placeholder="コメントする" rows="2" name="comment[content]" id="comment_content"> </textarea> <input type="submit" name="commit" value="コメントの投稿" data-disable-with="コメントの投稿" /> </form>

やりたいこと:トップページに表示されているPostにコメントを投稿する。

やったこと:http://nograve.hatenadiary.jp/entry/2015/11/05/161948を参考に、user_controllerのusers#showの部分を修正した。

このようにしても解決できませんでした。

なぜ、ParameterMissingが発生しているのか?
これを解決するにはどうすればいいのか?

以上についてご教示していただけないでしょうか?

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

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

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

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

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

guest

回答1

0

コメントのフォームの書き方が間違っています。

こういうときは,ログファイルを見て,どのようなリクエストが来て,Parameters がどんなかを見ます。
ログファイルじゃなくても,rails server したターミナル上で刻々とリクエストなどの情報が見えますよね。そこを見れば分かります。

フォームは

erb

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

となっていますよね。
まず,Comment モデルのコメント本文は content のはずなのに textareanametext になっているのがおかしいですが,エラーが出たのはそれ以前の問題です。

CommentsConrollercreate アクションでは,Comment オブジェクトを作るために,コントローラーの private メソッドである comment_params を使いますよね。その定義は

rb

1def comment_params 2 params.require(:comment).permit(:user_id, :post_id, :content) 3end

となっています。この require は,リクエストのパラメーター(ログに Parameters として見えているデータ)から comment をキーとする部分を取り出そうとするのですが,Parameters はきっと

Parameters: {"utf8"=>"✓", "authenticity_token"=>"云々", "text"=>"あいうえお"}

みたいになっているはずです。comment が見当たりませんね。これがエラーの原因です。

正しいフォームは,例えば以下のように書きます。

erb

1<%= form_for [post, Comment.new] do |form| %> 2 <%= form.text_area :content, cols: "30", placeholder: "コメントする", rows: "2" %> 3 <%= form.submit "コメントの投稿" %> 4<% end %>

いや,Rails 5.1 以降なら form_with を使うほうがいいのでしょうが,私が慣れていないためとりあえず form_for を使う書き方にしてみました。

ま,ともかく正しいフォームの場合,リクエストのパラメーターは

Parameters: {"utf8"=>"✓", "authenticity_token"=>"云々", "comment"=>{"content"=>"あいうえお"}, "commit"=>"コメントの投稿", "post_id"=>"1"}

みたいになったはずです。(長いので改行を入れました)

comment_paramsrequire(:comment) はこの中の "comment" をキーとする部分を持ってくるってことです。

投稿2018/01/22 13:57

編集2018/01/22 15:09
scivola

総合スコア2108

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

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

begin1990

2018/01/22 14:49 編集

ご回答ありがとうございます。 フォームの所を、おっしゃる通り <%= form_for [@post, Comment.new] do |form| %> <%= form.text_area :content, cols: "30", placeholder: "コメントする", rows: "2" %> <%= form.submit "コメントの投稿" %> <% end %> に変更したところ、再び「No route matches {:action=>"create", :controller=>"comments", :post_id=>nil} missing required keys: [:post_id]」が発生してしまいました。 エラー内容 https://gyazo.com/55934603a5abe2787d69b490a13d6e51 この場合、トップページコントローラのindexアクションに何か追加する必要はありますか?
scivola

2018/01/22 15:14

ごめんなさい,今の場合,コメントすべき Post は @post じゃなくて post に入っているんですね。なので,form_for に渡す配列の第一要素は @post でなく post としてください。(回答は修正しました) それから,エラー画面を見ると,私が書いた Comment.new を Comment.create に修正されているのと,ブロックパラメーターも form から f に修正されていますね。これがまずおかしいです。 それから routes.rb を見せてください。
begin1990

2018/01/22 15:28

申し訳ありません。せっかくご回答くださったのに、私の方で修正してしまって。 それと、ルーティングも追加しました。
scivola

2018/01/23 03:27

うーん,手元で同じようなのを作ってコメントが付けられることを確認しているんですが,どこかに見落としがあったかなあ。 では,/posts を表示したときのコメントのフォームの <form> タグの部分(ブラウザーで HTML ソースを表示してその HTML 断片)を見せてもらえますか。
begin1990

2018/01/23 10:48

フォームの <form> タグの部分を追加しました。
scivola

2018/01/25 23:21

もう一度,現在のエラーの情報を詳しく教えてもらえますか。 何をどうしたときにどこで(コードのどの部分で)どういうエラーが出たのかを。
begin1990

2018/01/26 03:53

只今仕事中ですので、返事は今夜になります。 よろしくお願いします。
begin1990

2018/01/26 12:32 編集

お待たせ致しました。 現在は、トップページにコメントを表示させるため、toppages#indexに、 @comment = @post.comments.build @comments = @post.comments.order('created_at DESC').page(params[:page]) を追加したところ、投稿したコメントが表示されていません。
scivola

2018/01/26 13:08

えっ? ParameterMissing の話はどうなったのですか。そっちは解決したのでしょうか?
begin1990

2018/01/26 13:10

そちらの方は大丈夫です。
scivola

2018/01/26 13:52

別の問題に移ったのでしたら,質問を新しく立てていただけますか。
begin1990

2018/01/26 14:34

わかりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問