Programming Journal

学習したことの整理用です。

【API】【Rails】エラーメモ

エラーを出しまくったので、繰り返さないようにメモ。

wrong number of arguments

Postmanを使って、articleの更新と削除を試していたのに、できない。 新規作成のPOSTと一覧取得のGETは問題なし。
コードは基礎的なものだしパッと見間違っていなそう…

f:id:Study-Diary:20201128090030p:plain
error

{
    "message": "Internal Server Error",
    "errors": [
        "wrong number of arguments (given 1, expected 0)"
    ]
}

wrong number of arguments引数の数が間違っている・・・?
他のアクションはできているので、createdestroyアクションに関わる箇所が間違ってそう。
ということでよくよく見直してみると、

module Api
  module V1
    class User::ArticlesController < BaseController
      before_action :set_article, only: %i[update destroy]
# 略

      def update
        if @article.update(article_params)
          json_string = ArticleSerializer.new(@article).serialized_json
          render json: json_string
        else
          render_400(nil, @article.errors.full_messages)
        end
      end

# 略
      private
# 略
      def set_article
        @article = current_user.articles.find(params(:id)) # ここ!!
      end
    end
  end
end

params[:id]だった。。。タイポで数時間悩んだ。

namespaceの重複

ユーザー登録用のコントローラーで、createアクションをPostmanで試してみるも、ユーザー登録できない。

module Api
  module V1
    class RegistrationsController < BaseController

      def create
        @user = User.new(user_params)
 …
# 略

ディレクトリ階層はこんな感じ。

f:id:Study-Diary:20201128093958p:plain
ディレクトリ階層

f:id:Study-Diary:20201128092551p:plain
Postman

undefined method 'new' for Api::V1::User::Module

エラー文をみると、Api::V1::User::Moduleでnewメソッドが定義されていない…?

これは自力で解決できずにギブアップしてしまいました。

結論は、「namespaceの重複を防ぐために、::Userとし、絶対参照にする。 」

ただ、理由が分かってなくて、Userという定数を探すためにrailsが自動で上から順番に探索してくるけど、見つからなかったからエラーになった??
以下のリンクを読んでぼんやりとしかまだ分かってないので今度まとめられたら…

 def create
   @user = ::User.new(user_params)

できた。

f:id:Study-Diary:20201128101226p:plain
Postman

Rubyにおけるクラス/モジュール定義関連の仕組みと、Ruby on Railsにおけるautoloadの仕組み - Qiita

ネームスペースが重複する場合はその定数の参照はコンテキストに依存しない絶対的な参照に変更したほうがいい。::User、Admin::Userのように

Railsのネストしたネームスペースのautoload - hokaccha memo

定数の自動読み込みと再読み込み (Classic) - Railsガイド

Rubyでクラス名のはじめに::(コロンを2つ)をつけるとそのクラスの絶対的な位置表現をすることができる - コード日進月歩