th_9plus
@th_9plus (たかちゃん)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

コメント投稿中 エラー Unknown action The action 'create' could not be found for CommentsController

コメント投稿 押すとこのエラーが出ました。
コントローラーの何が違っているのか分からないので教えて頂きたいです。
スクリーンショット 2020-09-11 18.14.01.png

comments.controller.rb
class CommentsController < ApplicationController

   before_action :authenticate_user!

  def create
    post = Post.find(params[:post_id])
    @comment = post.comments.build(comment_params)
    @comment.user_id = current_user.id
    if @comment.save
      flash[:success] = "コメントしました"
      redirect_back(fallback_location: root_path)
    else
      flash[:success] = "コメントできませんでした"
      redirect_back(fallback_location: root_path)
    end
  end

  private

    def comment_params
      params.require(:comment).permit(:content)
    end

end
routers.rb
Rails.application.routes.draw do

  devise_for :users
  get "login" => "users#login_form"


  post "login" => "users#login"
  post "logout" => "users#logout"


  post "users/:id/update" => "users#update"
  get "users/:id/edit" => "users#edit"
  post "users/create" => "users#create"
  get "singnup" => "users#new"
  get "users/index" => "users#index"
  get "users/:id" => "users#show"

  get "posts/index" => "posts#index"
  get "posts/new" => "posts#new"
  get "posts/:id" => "posts#show"

   resources :posts do
    resources :comments, only: [:create]
  end

  post "posts/create" => "posts#create"

  get "posts/:id/edit" => "posts#edit"

  post "posts/:id/update" => "posts#update"
  post "posts/:id/destroy" => "posts#destroy"
  get "/" => "home#top"
  get "about" => "home#about"

end

migrate/create_comments.rb
class CreateComments < ActiveRecord::Migration[6.0]
  def change
    create_table :comments do |t|
      t.string :content
      t.references :user, null: false, foreign_key: true
      t.references :post, null: false, foreign_key: true

      t.timestamps
    end
  end
end
model/comment.rb
class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :post
end
app/views/posts/show.html.erb
<div class="main posts-show">
  <div class="container">
    <div class="posts-show-item">
      <div class="post-user-name">
        <img src="<%= "/user_images/#{@user.image_name}" %>">
        <%= link_to(@user.name, "/users/#{@user.id}") %>
      </div>
      <p>
        <%= @post.content %>
      </p>

      <div class="post-time">
       <%= @post.created_at %>
       </div>
       <% if @post.user_id == @current_user.id %>
       <div class="post-menus">
        <%= link_to("編集", "/posts/#{@post.id}/edit") %>
        <%= link_to("削除", "/posts/#{@post.id}/destroy", {method: "post"}) %>
      </div>
      <% end %>
#ここから下がcomment関連です。

<div class="comment-wrapper border-top mb-10">
  <p class="mt-5">コメント一覧</p>
  <% @comments.each do |c| %>
    <div>
      <% unless c.user.blank? %>
        <a href="<%= user_path(c.user_id) %>"><%= image_tag c.user.image.to_s,
          class:"rounded-circle icon_image mr-3 mb-3"%></a>
        <% end %>
      <%= c.user.username unless c.user.blank? %>
      <br />
      <%= c.content %>
    </div>
    <br />
  <% end %>
  <% if user_signed_in? %>
    <%= form_with(model: [@post, @comment], local: true) do |f| %>
      <%= f.text_area :content, class: "form-control", rows: 5 %>
      <%= button_tag type: "submit", class: "btn btn-success float-right mt-1" do %>
        <i class="far fa-comments"></i> コメントする
      <% end %>
    <% end %>
  <% end %>
</div>
    </div>

  </div>

</div>

0

4Answer

すでに解決済みかもですが、ファイル名がcomment.controller.rbとなっていますが実際どうでしょう?

0Like

Comments

  1. @th_9plus

    Questioner

    あ、、、実際のファイルはcomments になってます。
    失礼しました。直しておきます。
    ちなみにまだ解決していないので教えて頂きたいです。

実際のファイルはcomments になってます。

ファイル名が’comments.rb’とか’comments.controller.rb’とかということですかね?

僕が勘違いしてるだけなら申し訳ないですが、もし↑なら’comments_controller.rb’にした方がいいかと思いました。

それでもダメならコントローラーファイルだけでは判断出来ないので、GitHubなどで他のファイルをみれる形にしてもらうか、config/routes.rb など、関連してそうなソースコードも載せて欲しいです。。!

0Like

Comments

  1. @th_9plus

    Questioner

    GitHubはしていません。
    なので関連しているファイルを更新しましたのでよろしくお願い致します。

コメントする」 ボタンで投稿ができるはずだけどできないった言ったところでしょうか?

一見普通に動きそうですが。。。

ちなみに

$ rake routes

だとcomments#createは確認できますか?

あとできれば親リソース('Post')のモデルとコントローラも見たいです(view側の@commentの生成場所がわからないので)

0Like

Comments

  1. @th_9plus

    Questioner

    エラーは起こらなかったです!
    ですがコメントするを押すとコメントしましたとかは出ずにログイン画面になっちゃいます
    何でなのでしょうか?
  2. > エラーは起こらなかったです!

    最初の画像に出てるエラーは別ですか?そのエラーを僕の環境で調べたところ、

    - メソッドを本当に用意してない
    - privateなどに入れられて参照できない

    くらいしか出せなかったので、ちょっと変だなとは思いましたが。

    今の状態としては

    > コメントするを押すとコメントしましたとかは出ずにログイン画面になっちゃいます

    という認識で大丈夫ですかね?

    あと、前のコメントに追記したのですが、親リソース('Post')のモデルとコントローラも見せてもらいたいです。。
  3. @th_9plus

    Questioner

    コメントするを押すとコメントしましたとかは出ずにログイン画面になっちゃいます

    という認識で大丈夫です!!
    よろしくお願い致します。

    ```posts_controller.rb

    class PostsController < ApplicationController
    before_action :authenticate_user
    before_action :ensure_correct_user, {only: [:edit, :update, :destroy]}

    def index
    @posts = Post.all.order(created_at: :desc)
    end

    def show
    @post = Post.find_by(id: params[:id])
    @user = @post.user
    @post = Post.find(params[:id])
    @comments = @post.comments
    @comment = @comments.build
    end





    def new
    @post = Post.new
    end

    def create
    @post = Post.new(
    content: params[:content],
    user_id: @current_user.id
    )
    if @post.save
    flash[:notice] = "投稿を作成しました"
    redirect_to("/posts/index")
    else
    render("posts/new")
    end
    end

    def edit
    @post = Post.find_by(id: params[:id])
    end

    def update
    @post = Post.find_by(id: params[:id])
    @post.content = params[:content]
    if @post.save
    flash[:notice] = "投稿を編集しました"
    redirect_to("/posts/index")
    else
    render("posts/edit")
    end
    end

    def destroy
    @post = Post.find_by(id: params[:id])
    @post.destroy
    flash[:notice] = "投稿を削除しました"
    redirect_to("/posts/index")
    end

    def ensure_correct_user
    @post = Post.find_by(id: params[:id])
    if @post.user_id != @current_user.id
    flash[:notice] = "権限がありません"
    redirect_to("/posts/index")
    end
    end

    end
    ```

    ```model/post.rb

    class Post < ApplicationRecord

    validates :content, {presence: true, length: {maximum: 140}}
    validates :user_id, {presence: true}
    has_many :comments

    def user
    return User.find_by(id: self.user_id)
    end

    end
    ```

  4. > 何でなのでしょうか?

    僕には一概に何とはわかりませんが、現状なんの問題が起きているかを明確にして、問題が起きてそうなポイントを絞っていけば大丈夫だと思います。

    この質問はおそらく僕以外の僕より詳しい方も多く見ているはずなので、僕らの会話から誰かが教えてくれるかも知れませんし。

    僕はあまり時間は割けられないのですが、頑張りましょう。。!
  5. @th_9plus

    Questioner

    丁寧にありがとうございます!
    頑張ります!!
  6. ちょっとうまくいくかわかりませんが、

    `models/post.rb`のshowアクション
    @comment = @comments.build

    @comment = Comment.new にするとどうでしょうか...。(commentsのコントローラでbuild走ってるので必要ないかと。Newでインスタンスだけあれば大丈夫そう。。。)

    あと、僕はform周りは触らないので的外れかもですが、`/views/posts/show.html.erb`の
    <%= form_with(model: [@post, @comment], local: true) do |f| %>

    <%= form_with(model: @comment, url: post_comments_path, method: :post, local: true) do |f| %>
    に変更してみるとかでどうでしょう(「*コメントする*」ボタンでログイン画面に遷移してしまうということなので無理やりcomment#createに持っていかせてます)

    またうまくいかなかったら、
    - エラーが起きる状況(errメッセージや、ページの状態、画像もあるといい)
    - エラーが関連していそうなソースコード(今回は追記してもらったのでOK)
    - 自身で考えたエラーの原因(頼ってしまうと学びにならないので)
    をまとめておいてもらえるととても回答者も考えやすいです!!
  7. @th_9plus

    Questioner

    comment.new に関しましては正常に動いてます!!

    <%= form_with(model: @comment, url: post_comments_path, method: :post, local: true) do |f| %>
    に変更しましたが↑がエラーになりました!
    これがエラー文です。
    ActionController::UrlGenerationError in Posts#show
    Showing /home/ubuntu/environment/hello_app/app/views/posts/show.html.erb where line #37 raised:
    No route matches {:action=>"create", :controller=>"comments", :id=>"2"}, missing required keys: [:post_id]

    画像を添付したいのですがコメントからは添付できなかったので申し訳ございません。

    route の位置を変えたりしてみましたがエラーは変わらずでした。
  8. > comment.newに関しましては正常に動いてます!!
    @comments.buildの時動かなかった→Comment.newに修正して直ったということですか?(それで実際Commentは投稿できているのかなども知りたいです。。!)
    それとも元々その処理が正常に動いているから修正不要だったということでしょうか?

    `form_with`は僕の修正案前でも動かない感じですかね?(あと「コメントする」ボタンを押してcomments#createが呼び出されてない場合の対処なので、createを通っていれば元のままで大丈夫ですよ!)
  9. @th_9plus

    Questioner

    comment.newに関しましては正常に動いてます!!について言葉足らずで申し訳ないです。
    エラーは起きてませんが前回と変わらず「コメントする」ボタンを押してログインに移行してしまうのは変わりないです。元々正常に動いていたと思われるので修正は不要だったかもしれないです。

    `form_with`は僕の修正案前でも動かない感じですかね?については修正前もcomments#createが呼び出されてないです。
  10. > 言葉足らずで申し訳ないです。
    情報量が多い方がこちらとしては判断材料が増えるので助かります!

    > 元々正常に動いていたと思われるので修正は不要だったかもしれないです。
    今回の問題に絞ってみればそうですね。冗長な説明にはなりますがbuildだと、
    @commentのインスタンス生成→親レコードのインスタンスの主キーを子インスタンス(@comment)の外部キーとして設定。という手間が増えます。デメリットとしては
    - このような処理で単純に処理が重くなる(学習をすすめ大規模になる程大きなボトルネックを生むことがある)
    - チーム開発だと他の人がなにを意図してわざわざbuildにしてるかわからない
    に繋がるので避けましょう(お節介は承知ですが大切なので。。。あとこれに関しての返信は不要です!)

    > 修正前もcomments#createが呼び出されてないです。
    ですよね。。
    あまりやりたくないですが、ルーティングに
    resources :comments, only: [:create]
    をネストしないで置いてみて、先ほどのform_withのところを、
    <%= form_with(model: @comment, url: comments_path, method: :post, local: true) do |f| %>
    にしてみてください。(これも無理やり`comments#create`を呼び出すため)

    @th_9plus さんとしては多分ルーティングをネストさせたいかとは思いますが、とりあえず動く形にして動いたらリファクタリングしていきましょう。
    エラーや意図してない場合はまたその状況を教えてください!
  11. @th_9plus

    Questioner

    丁寧にありがとうございます!!
    勉強になります!!
    <%= form_with(model: @comment, url: comments_path, method: :post, local: true) do |f| %>

    に変更しましたがこのようなエラーが出ました。
    NameError in Posts#show
    Showing /home/ubuntu/environment/hello_app/app/views/posts/show.html.erb where line #37 raised:
    undefined local variable or method `comments_path' for #<#<Class:0x00007f7a282bb5c0>:0x0000558d27035b38>
    Did you mean? @comments

    変更した場所がエラーになりました。↓
    <%= form_with(model: @comment, url: comments_path, method: :post, local: true) do |f| %>
  12. んーやっぱりルーティング周りがちょっと怪しそう。。。

    $ rake routes の実行結果を教えてください!(commentsとpost関連だけでも大丈夫です)
  13. @th_9plus

    Questioner

    posts_index GET /posts/index(.:format) posts#index
    posts_new GET /posts/new(.:format) posts#new
    GET /posts/:id(.:format) posts#show
    post_comments POST /posts/:post_id/comments(.:format) comments#create
    posts GET /posts(.:format) posts#index
    POST /posts(.:format) posts#create
    new_post GET /posts/new(.:format) posts#new
    edit_post GET /posts/:id/edit(.:format) posts#edit
    post GET /posts/:id(.:format) posts#show
    PATCH /posts/:id(.:format) posts#update
    PUT /posts/:id(.:format) posts#update
    DELETE /posts/:id(.:format) posts#destroy
    posts_create POST /posts/create(.:format) posts#create
    GET /posts/:id/edit(.:format) posts#edit
    POST /posts/:id/update(.:format) posts#update
    POST /posts/:id/destroy(.:format) posts#destroy
    GET / home#top
    about GET /about(.:format) home#about

    こちらで大丈夫でしょうか?

先程

ルーティングに
resources :comments, only: [:create]
をネストしないで置いてみて、

と書いたと思うのですが多分追加してないですかね笑

0Like

Comments

  1. @th_9plus

    Questioner

    失礼しました!!
    こちらが変更後です!!

    POST /login(.:format) users#login
    logout POST /logout(.:format) users#logout
    POST /users/:id/update(.:format) users#update
    GET /users/:id/edit(.:format) users#edit
    users_create POST /users/create(.:format) users#create
    singnup GET /singnup(.:format) users#new
    users_index GET /users/index(.:format) users#index
    GET /users/:id(.:format) users#show
    posts_index GET /posts/index(.:format) posts#index
    posts_new GET /posts/new(.:format) posts#new
    GET /posts/:id(.:format) posts#show
    comments POST /comments(.:format) comments#create
    posts_create POST /posts/create(.:format) posts#create
    GET /posts/:id/edit(.:format) posts#edit
    POST /posts/:id/update(.:format) posts#update
    POST /posts/:id/destroy(.:format) posts#destroy
    GET / home#top
    about GET /about(.:format) home#about

Your answer might help someone💌