RailsでActive Storageを使って画像も投稿できるツイッターのようなものを作ろうとしていたのですが、それをしている途中でRouting Errorになってしまいました。
Routing Error
No route matches [POST] "/posts/new"
今回はその解決法と、投稿が表示される仕組みから今回どうしてエラーが解決できたのかを自分なりにまとめていきたいと思います。
エラーになってしまったcontrollerがあるのでそちらを見ていきたいと思います。
いかがそのcontrollerの部分のコードです。
class PostsController < ApplicationController
before_action :authenticate_user!, only: [:new, :update, :create, :edit, :update, :destroy]
before_action :find_post, only: [:edit, :update, :show, :destroy]
def index
@posts = Post.all
@like = Like.new
end
def new
@like = Like.new
end
def show
end
def create
@post = current_user
@post = Post.create(post_params)
if @post.save
redirect_to root_path,notice:'投稿に成功しました'
else
redirect_to new_post_path,notice:'投稿に失敗しました'
end
end
def edit
end
def update
@post.update(post_params)
end
def destroy
if @post.destroy
redirect_to root_path,alert: '投稿を削除しました'
else
redirect_to root_path
end
end
private
def post_params
params.require(:post).permit(:content, images: []).merge(user_id: current_user.id)
end
def find_post
@post = Post.find(params[:id])
end
def force_redirect_unless_my_post
return redirect_to root_path,alert:'権限がありません'if @post.user != current_user
end
end
@like
などの物が入っていますが、それはいま高評価機能を作っているからそうなっています。
そして今回の原因なのですが、newメソッドの中にpostのnewメソッドというオブジェクトという今回でいうと投稿を作る機能を入れておく器を作るコードが書いていないからです。
当たり前ですがRailsは
Routing
→Controller
→model
→view
の順番で動いていきます。
ですが、仮にRoutingまで行けたとしても、そこから先のControllerで指定されたActionを用意できないとRouting errorになってしまいます。
ですので、正しいコードはこちらになります
#正しいコード
class PostsController < ApplicationController
before_action :authenticate_user!, only: [:new, :update, :create, :edit, :update, :destroy]
before_action :find_post, only: [:edit, :update, :show, :destroy]
def index
@posts = Post.all
@like = Like.new
end
def new
@post = Post.new
@like = Like.new
end
def show
end
def create
@post = current_user
@post = Post.create(post_params)
if @post.save
redirect_to root_path,notice:'投稿に成功しました'
else
redirect_to new_post_path,notice:'投稿に失敗しました'
end
end
def edit
end
def update
@post.update(post_params)
end
def destroy
if @post.destroy
redirect_to root_path,alert: '投稿を削除しました'
else
redirect_to root_path
end
end
private
def post_params
params.require(:post).permit(:content, images: []).merge(user_id: current_user.id)
end
def find_post
@post = Post.find(params[:id])
end
def force_redirect_unless_my_post
return redirect_to root_path,alert:'権限がありません'if @post.user != current_user
end
end
ここの
newメソッドの中に注目してください
def new
@post = Post.new
@like = Like.new
end
@post = Post.new
が加わっているので、投稿(post)のオブジェクトが作られています。
これにより、Routingで指定したアクションが用意されているのでエラーが解決できるわけです。
皆さん是非参考にしてみてください
#最後に
今回terateilさんで質問をして回答をしていただきました。
今回質問を回答していただいたので、その方のURLをはらせていただきます。
この場でお礼申し上げます
https://teratail.com/users/maisumakun#reply