0
0

More than 3 years have passed since last update.

Active Storageで画像投稿とツイート機能を実装しようとしたらエラーになってしまいました

Last updated at Posted at 2021-03-25

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は
RoutingControllermodelviewの順番で動いていきます。
ですが、仮に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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0