前提・実現したいこと
rails で簡単な写真の投稿アプリを作っています。
写真の詳細画面に、コメントを表示させたいです。
写真とコメントはそれぞれ違うモデルを用意し、ネストしてます。
コメントの実装には、「ActionCable」を使用し、非同期で表示させたいです。
コメントの投稿ボタンを押すと、エラーが発生してしまいます。
これを解決したいです。
発生している問題・エラーメッセージ
No template found for CommentsController#create, rendering head :no_content Completed 204 No Content in 25ms (ActiveRecord: 2.8ms | Allocations: 8252)
該当のソースコード
html
1[photos/show.html.erb] 2 3<%= render "shared/second_header" %> 4<div class="post_photo"> 5 <div class="main-categorys"> 6 <h2 class="main-menu">menu</h2> 7 <ul class="main-category"> 8 <li>category</li> 9 <li>runkking</li> 10 </ul> 11</div> 12 13<div class="show-content"> 14 <div class="show-photos"> 15 <div class="show-title"> 16 <%= @photo.title %> 17 </div> 18 <div class="show-photo"> 19 <%= image_tag @photo.image, class:"show-img"%> 20 </div> 21 <div class="show-nickname"> 22 <%= @photo.user.nickname %> 23 </div> 24 <div class="show-btn"> 25 <% if user_signed_in? && current_user.id %> 26 <%= link_to "編集", edit_photo_path, class:"show-edit-btn", id:"show-edit-btn" %> 27 <%= link_to "削除", photo_path, method: :delete, class:"show-delete-btn", id:"show-delete-btn" %> 28 <% end %> 29 </div> 30 </div> 31</div> 32 33<div class="show-comments"> 34 <% if user_signed_in? %> 35 <%= form_with(model: [@photo, @comment]) do |f| %> 36 <%= f.text_field :text %> 37 <%= f.submit "投稿" %> 38 <% end %> 39 <% else %> 40 <strong><p>※※※ コメントの投稿には新規登録/ログインが必要です ※※※</p></strong> 41 <% end %> 42 <div class="comments", id='comments'> 43 <% @comments.reverse_each do |comment| %> 44 <p><%= comment.text %></p> 45 <% end %> 46 </div> 47</div> 48 49<%= render "shared/footer" %>
ruby
1[controllers/comment_controller] 2 3class CommentsController < ApplicationController 4 def new 5 @photo = Photo.find(params[id]) 6 comments = Comment.all 7 comment = Comment.new 8 end 9 10 def create 11 @photo = Photo.find(params[:photo_id]) 12 comment = Comment.new(comment_params) 13 if comment.save 14 ActionCable.server.broadcast 'comment_channel', comment: data['comment'] 15 end 16 end 17 18 private 19 20 def comment_params 21 params.permit(:text).merge(user_id: current_user.id, photo_id: params[:photo_id]) 22 end 23end
ruby
1[controllers/photo_controller] 2 3class PhotosController < ApplicationController 4 before_action :find_params, except: [:index, :new, :create] 5 before_action :authenticate_user!, only: [:new, :edit] 6 7 8 def index 9 @photos = Photo.order(created_at: :desc) 10 end 11 12 def new 13 @photo = Photo.new 14 end 15 16 def create 17 @photo = Photo.new(post_params) 18 if @photo.save 19 redirect_to root_path 20 else 21 render :new 22 end 23 end 24 25 def show 26 @comment = Comment.new 27 @comments = @photo.comments.includes(:user) 28 end 29 30 def edit 31 end 32 33 def update 34 if @photo.update(post_params) 35 redirect_to root_path 36 else 37 render :edit 38 end 39 end 40 41 def destroy 42 if @photo.destroy 43 redirect_to root_path 44 end 45 end 46 47 private 48 49 def find_params 50 @photo = Photo.find(params[:id]) 51 end 52 53 def post_params 54 params.require(:photo).permit(:image, :title, :category_id).merge(user_id: current_user.id) 55 end 56end
javascript
1[javascript/channels/comment_channel.js] 2 3import consumer from "./consumer" 4 5consumer.subscriptions.create("CommentChannel", { 6 connected() { 7 // Called when the subscription is ready for use on the server 8 }, 9 10 disconnected() { 11 // Called when the subscription has been terminated by the server 12 }, 13 14 received(data) { 15 const html = `<p>${data.comment.text}</p>`; 16 const comment = document.getElementById('comments') 17 const newComment = document.getElementById('comment_text'); 18 newComment.value=''; 19 } 20});
ruby
1[app/channels/comment_channel.rb] 2 3class CommentChannel < ApplicationCable::Channel 4 def subscribed 5 stream_from "comment_channel" 6 end 7 8 def unsubscribed 9 # Any cleanup needed when channel is unsubscribed 10 end 11end
ruby
1[models/comennt.rb] 2 3class Comment < ApplicationRecord 4 belongs_to :photo 5 belongs_to :user 6 7 validates :text, presence: true 8end
ruby
1[models/photo.rb] 2 3class Photo < ApplicationRecord 4 has_one_attached :image 5 belongs_to :user 6 has_many :comments 7 8 extend ActiveHash::Associations::ActiveRecordExtensions 9 belongs_to :category 10 11 with_options presence: true do 12 validates :title 13 validates :image 14 validates :category_id , numericality: { other_than: 0 } 15 end 16 17end
ruby
1[models/user.rb] 2 3class User < ApplicationRecord 4 # Include default devise modules. Others available are: 5 # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable 6 devise :database_authenticatable, :registerable, 7 :recoverable, :rememberable, :validatable 8 9 with_options presence: true do 10 validates :last_name 11 validates :first_name 12 validates :nickname, length: { maximum: 8 } 13 validates :email, uniqueness: {case_sensitive: true} 14 validates :password, length: { minimum: 6 }, format: { with: /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i } 15 end 16 17 has_many :photos 18 has_many :comments 19end
試したこと
1.htmlファイルがうまく設定できてない
エラーの意味を調べたところ、うまくviewファイルを見つけられなかったとのことだった。
確かに、「CommentController」は「#new」なのに、
私がviewを書いているのは「view/photos/show.html.erb」。
それが原因なのだろうか?
2.「view/comments/new.html.erb」ファイルを作ってみたがだめだった
「view/comments/new.html.erb」を作って、
「view/photos/show.html.erb」に部分テンプレートとして読み込ませてみた。
これでもダメだった。
補足情報(FW/ツールのバージョンなど)
ruby '2.6.5'
rails '~> 6.0.0'
あなたの回答
tips
プレビュー