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

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

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

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

Q&A

解決済

1回答

1986閲覧

コメントがトップページに表示されません

begin1990

総合スコア31

Ruby

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

0グッド

0クリップ

投稿2018/01/26 14:49

編集2018/02/04 07:39

やりたいこと
トップページにコメント一覧を表示させる

問題点
https://gyazo.com/e07751929a071e6d52390b314ae87ae0の画面で、コメント投稿をしたところ、コメントがトップページに表示されません(コンソール上ではコメントが保存されいています)。

現在のコードは以下の通りです。
toppages.controller.rb

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]) @post_comment = current_user.post_comments.build @post_comments = @post.post_comments.order('created_at DESC').page(params[:page]) end end end

posts_controller.rb

class PostsController < ApplicationController before_action :require_user_logged_in before_action :correct_user, only: [:destroy] def index @post_comment = current_user.post_comments.build end def show @post = Post.includes(:user).find(params[:id]) end def create @post = current_user.posts.build(post_params) if @post.save flash[:success] = 'メッセージを投稿しました。' redirect_to root_url else @posts = current_user.feed_posts.order('created_at DESC').page(params[:page]) flash.now[:danger] = 'メッセージの投稿に失敗しました。' render 'toppages/index' end end def destroy @post.destroy flash[:success] = 'メッセージを削除しました。' redirect_back(fallback_location: root_path) end private def post_params params.require(:post).permit(:picture, :content) end def correct_user @post = current_user.posts.find_by(id: params[:id]) unless @post redirect_to root_url end end end

post_comments.controller.rb

class PostCommentsController < ApplicationController before_action :require_user_logged_in before_action :correct_user, only: [:destroy] def create @post = Post.find(params[:post_id]) @post_comment = @post.post_comments.create(post_comment_params) @post_comment.user_id = current_user.id #@post_comment = current_user.post_comments.build(post_comment_params) #@comment = Comment.create(text: comment_params[:text], post_id: comment_params[:post_id], user_id: current_user.id) if @post_comment.save flash[:success] = "コメントしました。" #redirect_to "/posts/#{@comment.post.id}" #redirect_to post_comments_path(@post.id) #redirect_to :action =>"new" redirect_to root_url else @post_comments = @post.post_comments.order('created_at DESC').page(params[:page]) flash.now[:danger] = 'コメントの投稿に失敗しました。' render 'toppages/index' end end def destroy @post_comment.destroy flash[:success] = 'コメントを削除しました。' redirect_back(fallback_location: root_path) end private # Use callbacks to share common setup or constraints between actions. def set_post_comment @post = Post.find(params[:post_id]) @post_comment = @post.post_comments.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def post_comment_params params.require(:post_comment).permit(:user_id, :post_id, :content) end def correct_user @post_comment = current_user.post_comments.find_by(id: params[:id]) unless @post_comment redirect_to root_path end end end

comments/_comments.html.erb

<ul class="media-list"> <% @post_comments.each do |post_comment| %> <% user = post_comment.user %> <div> <p>投稿者:<%= link_to user.name, user_path(user) %> <span class="text-muted">commented at <%= post_comment.created_at %></span></p> </div> <p><%= post_comment.content %></p> <div> <% if current_user == post_comment.user %> <%= link_to "削除", post_comment, method: :delete, data: { confirm: "本当に削除してよろしいですか?" }, class: 'btn btn-danger btn-sm' %> <% end %> </div> <% end %> <%= paginate @post_comments %> </ul>

posts/_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> <%= render 'comments/comments', post_comments: @post_comments %> <br/> <% if current_user %> <%= form_for [post, Comment.new] do |form| %> <%= form.text_area :content, cols: "30", placeholder: "コメントする", rows: "2" %> <%= form.submit "コメントの投稿" %> <% 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>

toppages/index.html.erb

<% if logged_in? %> <div class="row"> <aside class="col-md-4"> <%= form_for(@post, html: {multipart: true}) do |f| %> <div class="form-group"> <%= f.label :picture, '写真' %> <%= f.file_field :picture %><br /> <%= f.label :content, 'コンテンツ' %> <%= f.text_area :content, class: 'form-control', rows: 5 %> </div> <%= f.submit '投稿', class: 'btn btn-primary btn-md' %> <% end %> </aside> <div class="col-xs-8"> <%= render 'posts/posts', posts: @posts %> </div> </div> <% else %> <div class="cover"> <div class="cover-inner"> <div class="cover-contents"> <h1>毎日のつながりは、ここから始まる</h1>> <%= link_to 'まずは会員登録から', signup_path, class: 'btn btn-success btn-md' %> <%= link_to '会員の方はこちら', login_path, class: 'btn btn-success btn-md' %> </div> </div> </div> <% end %>

toppages_controller.rbに

@post_comment = current_user.post_comments.build @post_comments = @post.post_comments.order('created_at DESC').page(params[:page])

を入れれば表示されると思っていましたが、全く表示されませんでした。

他にも色々試しましたが、それでもコメントは表示されませんでした。
これ以上、トップページに投稿したコメントを表示させる方法がわからないので、どなたかご教示をお願いできませんか?

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

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

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

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

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

scivola

2018/02/04 06:53

各ビューのところに,そのテンプレートファイルのパスを追記してもらえますか。
begin1990

2018/02/04 07:15

各ビューのところに,そのテンプレートファイルのパスを追記したつもりですが、「○○.html.erb」という形でよろしいでしょうか?
scivola

2018/02/04 07:35

ファイル名だけじゃなくてファイルパスを書いてほしいんです。app/views は略してもいいですが,そのあとのディレクトリー名は略さないで。なぜかというと,そのファイルがどこに置かれているか,ということがとても重要なので。
begin1990

2018/02/04 07:40

ファイルパスも追記しました。
guest

回答1

0

ベストアンサー

posts/posts ビューの

rb

1render 'comments/comments', comments: @comments

rb

1render 'comments/comments', comments: post.comments

に変えたらどうなりますか?

投稿2018/02/03 15:53

scivola

総合スコア2108

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

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

begin1990

2018/02/04 04:38 編集

それでも変わりませんでした。 というのは、toppages_controller内の@postは、入力用にbuildされた新しいモデルのインスタンスなので、当然@post.commentsは空っぽになるからです。
scivola

2018/02/04 04:52

@post じゃなくて post ですよ?
begin1990

2018/02/04 05:04

トップページコントローラの8行目を、 @post_comments = post.post_comments.order('created_at DESC').page(params[:page]) に変える、ということでしょうか?
scivola

2018/02/04 06:51

いえ,そうではありません。 私が提示したコードでは `@post` を使っていないのに `@post` の話をされているので,何か誤解があるのでは,と。
begin1990

2018/02/04 07:19

ごめんなさい。もしかするとtoppages_controllerの@postが関係しているのかなと思いまして、その話をしてしまいました。 <%= render 'comments/comments', post_comments: post.post_comments %>にしても変わりありませんでした。 また、commentsは、postと区別しやすくしたいため、全体的に「post_comments」に変えてあります(modelはpost_comment、テーブルはpost_comments、等)。
scivola

2018/02/04 07:57 編集

質問投稿時からコードを書き換えられると話がこんがらがるので,変えないでください。 現状のコードに即していうと, toppages/index.html.erb で render 'posts/posts', posts: @posts とやって,posts/_posts.html.erb を呼び出しているんですよね? で,そのとき,posts っていうローカル変数を渡してますよね? で,posts.html.erb において posts.each do |post| # 云々 end というループを回してますよね。 ループの中では,post というブロックパラメーターに個々の Post オブジェクトが入っているわけですよね。 で,そのループの中で,post.content を表示してますよね。 その直後に,その post のコメント一覧を表示したいわけですよね。 そのコメント一覧は comments/_comments.html.erb で表示するんですよね。 そのため render を使うわけですが, render 'comments/comments', post_comments: @post_comments となっているのがおかしいです。 なぜここでいきなり @post_comments が出てくるのですか。 post のコメントたちは post.comments で得られるはずです。それを渡してやらなければなりません。 つまり,正しくは render 'comments/comments', post_comments: post.comments です。 さっきから書いているのはそのことです。 で,comments/_comments.html.erb の中身もおかしいです。 せっかくローカル変数 post_comments が渡されているのに,それを使わず @post_comments.each do |post_comment| # 云々 end と,インスタンス変数 @post_comments を使っています。これを post_comments に変えましょう。 これで直りませんか?
begin1990

2018/02/04 08:06

ありがとうございます。 おかげで解決できました!
scivola

2018/02/04 08:21

ああよかった。 現状では,不要なインスタンス変数定義(代入)がいろいろ残っているので,要らないのは消しておきましょうね。 コントローラーのアクションとテンプレートおよび部分テンプレートの間の値の受け渡し方法について。 コントローラーからはインスタンス変数で渡します。コントローラーで代入さえしておけば,ほかには何もしなくても,テンプレートおよびその先の部分テンプレートで参照できます。 一方,テンプレートから部分テンプレートへはすでに見たような方法で,ローカル変数として渡します。render メソッドのオプションのハッシュのキーの名前が,部分テンプレート側で参照できるローカル変数の名前になります。 というようなことが理解できていれば,今後は惑わずに済むのではないでしょうか。
begin1990

2018/02/04 08:50

つまり、先ほどの例で言うと、「posts/_posts.html.erb」から、「post_comments/_post_comments.html.erb」へ値を渡す際は、ローカル変数として渡す、という考えでよろしいでしょうか?
scivola

2018/02/04 09:12

そうです。
begin1990

2018/02/04 09:27

ご説明ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問