💎
Railsで ActionNotFound: The action could not be found と表示される
問題
Railsでこのようなコードを実装しました。
class UsersController < ApplicationController
# GET /users
def index
@users = User.all
render json: @users
end
...
private
def user_params
params.require(:user).permit(
:department_id,
:name,
:birthday
)
end
# DELETE /users/:id
def destroy
@user = User.find(params[:id])
if @user
@user.destroy
render json: { message: 'User deleted successfully' }, status: :no_content
else
render json: { error: 'User not found' }, status: :not_found
end
end
end
http://localhost:3000/users/1
を呼び出したところ、以下のエラーが表示されました。
"status": 404,
"error": "Not Found",
"exception": "#<AbstractController::ActionNotFound: The action 'destroy' could not be found for UsersController>",
404なのでidが一致するUserが見つからなかったようでもありますが、エラー文にThe action 'destroy' could not be found
とあるので、destroy
メソッドが見つからない、ということのようです。しっかり書いてるのに…
解決方法
private
の下にdestroy
メソッドを記述してたのがいけなかったようです。
このように、destroy
とprivate
以下を入れ替えたらうまく行きました。
# DELETE /users/:id
def destroy
@user = User.find(params[:id])
if @user
@user.destroy
render json: { message: 'User deleted successfully' }, status: :no_content
else
render json: { error: 'User not found' }, status: :not_found
end
end
private
def user_params
params.require(:user).permit(
...
原因
rubyでは、private
と1行だけ書くとその下に書いてあるメソッドは全てprivate
扱いされるようで、他の場所から呼び出すことができなくなります。知らない仕様だった。
また、def
の前にprivate
を書けばこのようなことは起こりません。
private def user_params
params.require(:user).permit(
...
この場合は下にdestroy
を書いても大丈夫。
余談
Railsチュートリアルの最大手Railsをはじめようでは、private
が改行されて書かれています。
7.3.2 Strong Parametersを使う
private
def article_params
params.require(:article).permit(:title, :body)
end
これを参考に書いたのでうまくいかなかったようですね…
Discussion