0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails】resoucesを使用しても、editやdestroyでActionController::RoutingErrorとエラーが発生してしまう場合について

Last updated at Posted at 2021-05-03

症状

Rails6.0.3のAPIモードでeditアクションに対してアクセスしようとしたとき、下記エラーが発生しアクセスできませんでした。 No route matches「ルーティングがマッチしていない」と怒られています。
route.rb
ActionController::RoutingError (No route matches [GET] "/api/v1/hoges/2/edit"):

actionpack (6.0.3.6) lib/action_dispatch/middleware/debug_exceptions.rb:36:in `call'
actionpack (6.0.3.6) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (6.0.3.6) lib/rails/rack/logger.rb:37:in `call_app'
railties (6.0.3.6) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (6.0.3.6) lib/active_support/tagged_logging.rb:80:in `block in tagged'
activesupport (6.0.3.6) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (6.0.3.6) lib/active_support/tagged_logging.rb:80:in `tagged'
railties (6.0.3.6) lib/rails/rack/logger.rb:26:in `call'
actionpack (6.0.3.6) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.2.3) lib/rack/runtime.rb:22:in `call'
activesupport (6.0.3.6) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (6.0.3.6) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.0.3.6) lib/action_dispatch/middleware/static.rb:126:in `call'
rack (2.2.3) lib/rack/sendfile.rb:110:in `call'
actionpack (6.0.3.6) lib/action_dispatch/middleware/host_authorization.rb:82:in `call'
rack-cors (1.1.1) lib/rack/cors.rb:100:in `call'
railties (6.0.3.6) lib/rails/engine.rb:527:in `call'
puma (4.3.7) lib/puma/configuration.rb:228:in `call'
puma (4.3.7) lib/puma/server.rb:713:in `handle_request'
puma (4.3.7) lib/puma/server.rb:472:in `process_client'
puma (4.3.7) lib/puma/server.rb:328:in `block in run'
puma (4.3.7) lib/puma/thread_pool.rb:134:in `block in spawn_thread'

ルーティングを確認すると、何となく問題なさそうです。
resouceだと、特定のデータにアクセスするようなルーティングは制限されますが、今回使っているのはeditやshowなどの特定のデータにアクセスできるアクションにも対応できるようにしています。

route.rb
Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :fugasdo
        resources :hoges
      end
      resources :hoges
    end
  end
end

実際にどのようなルーティングが存在しているかをrake routesで確認します。

rakeroutes
 rake routes

                               Prefix Verb   URI Pattern                                                                              Controller#Action
              api_v1_fuga_hoges GET    /api/v1/fugas/:fuga_id/hoges(.:format)                                       api/v1/hoges#index
                                      POST   /api/v1/fugas/:fuga_id/hoges(.:format)                                       api/v1/hoges#create
               api_v1_fugat_food GET    /api/v1/fugas/:fuga_id/hoges/:id(.:format)                                   api/v1/hoges#show
                                      PATCH  /api/v1/fugas/:fuga_id/hoges/:id(.:format)                                   api/v1/hoges#update
                                      PUT    /api/v1/fugas/:fuga_id/hoges/:id(.:format)                                   api/v1/hoges#update
                                      DELETE /api/v1/fugas/:fuga_id/hoges/:id(.:format)                                   api/v1/hoges#destroy
                   api_v1_fugas GET    /api/v1/fugas(.:format)                                                            api/v1/fugas#index
                                      POST   /api/v1/fugas(.:format)                                                            api/v1/fugas#create
                    api_v1_fugat GET    /api/v1/fugas/:id(.:format)                                                        api/v1/fugas#show
                                      PATCH  /api/v1/fugas/:id(.:format)                                                        api/v1/fugas#update
                                      PUT    /api/v1/fugas/:id(.:format)                                                        api/v1/fugas#update
                                      DELETE /api/v1/fugas/:id(.:format)                                                        api/v1/fugas#destroy
                         api_v1_hoges GET    /api/v1/hoges(.:format)                                                                  api/v1/hoges#index
                                      POST   /api/v1/hoges(.:format)                                                                  api/v1/hoges#create
                          api_v1_food GET    /api/v1/hoges/:id(.:format)                                                              api/v1/hoges#show
                                      PATCH  /api/v1/hoges/:id(.:format)                                                              api/v1/hoges#update
                                      PUT    /api/v1/hoges/:id(.:format)                                                              api/v1/hoges#update
                                      DELETE /api/v1/hoges/:id(.:format)                                                              api/v1/hoges#destroy
        rails_postmark_inbound_emails POST   /rails/action_mailbox/postmark/inbound_emails(.:format)                                  action_mailbox/ingresses/postmark/inbound_emails#create
           rails_relay_inbound_emails POST   /rails/action_mailbox/relay/inbound_emails(.:format)                                     action_mailbox/ingresses/relay/inbound_emails#create
        rails_sendgrid_inbound_emails POST   /rails/action_mailbox/sendgrid/inbound_emails(.:format)                                  action_mailbox/ingresses/sendgrid/inbound_emails#create
  rails_mandrill_inbound_health_check GET    /rails/action_mailbox/mandrill/inbound_emails(.:format)                                  action_mailbox/ingresses/mandrill/inbound_emails#health_check
        rails_mandrill_inbound_emails POST   /rails/action_mailbox/mandrill/inbound_emails(.:format)                                  action_mailbox/ingresses/mandrill/inbound_emails#create
         rails_mailgun_inbound_emails POST   /rails/action_mailbox/mailgun/inbound_emails/mime(.:format)                              action_mailbox/ingresses/mailgun/inbound_emails#create
       rails_conductor_inbound_emails GET    /rails/conductor/action_mailbox/inbound_emails(.:format)                                 rails/conductor/action_mailbox/inbound_emails#index
                                      POST   /rails/conductor/action_mailbox/inbound_emails(.:format)                                 rails/conductor/action_mailbox/inbound_emails#create
        rails_conductor_inbound_email GET    /rails/conductor/action_mailbox/inbound_emails/:id(.:format)                             rails/conductor/action_mailbox/inbound_emails#show
                                      PATCH  /rails/conductor/action_mailbox/inbound_emails/:id(.:format)                             rails/conductor/action_mailbox/inbound_emails#update
                                      PUT    /rails/conductor/action_mailbox/inbound_emails/:id(.:format)                             rails/conductor/action_mailbox/inbound_emails#update
                                      DELETE /rails/conductor/action_mailbox/inbound_emails/:id(.:format)                             rails/conductor/action_mailbox/inbound_emails#destroy
rails_conductor_inbound_email_reroute POST   /rails/conductor/action_mailbox/:inbound_email_id/reroute(.:format)                      rails/conductor/action_mailbox/reroutes#create
                   rails_service_blob GET    /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
            rails_blob_representation GET    /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
                   rails_disk_service GET    /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
            update_rails_disk_service PUT    /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
                 rails_direct_uploads POST   /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create

上記の中に「edit」に該当するルーティングは存在しませんでした。
resoucesを使っても[edit」のルーティングが存在しないようです。

調べてみると、Railsガイドの「浅いネスト」に今回の原因となりそうな記述がありました。
要約すると、「親スコープ(fuga)の中でidを指定しないアクションのみを生成できる」というものでした。

つまり、今回のhugaに関するルーティングでは、routeファイルが上から読み込まれている関係上、最初にfuga以下にあったhogeリソースにヒットし、そこではid指定があるアクションが生成されていなかったから、このようになってしまったのかと思いましたが、resoucesの順序を変更してもルーティングにeditが追加されませんでした。

解決方法

resoucesで使用するアクションを明示的に書いたら、ルーティングエラーが出なくなりました。
route.rb
resources :hoges,only: [:index, :show, :new, :create, :destroy, :edit, :update] do
end

RailsAPIモードだったので、生成されるルーティングは下記になります。
ゆえに、editやdestroyなどがルーティングでそもそも生成されない仕様で、resoucesでも使えないようです。

rakeroutes
rake routes
api_v1_posts GET    /api/v1/posts(.:format)     api/v1/posts#index
             POST   /api/v1/posts(.:format)     api/v1/posts#create
 api_v1_post GET    /api/v1/posts/:id(.:format) api/v1/posts#show
             PATCH  /api/v1/posts/:id(.:format) api/v1/posts#update
             PUT    /api/v1/posts/:id(.:format) api/v1/posts#update
             DELETE /api/v1/posts/:id(.:format) api/v1/posts#destroy

参考

Railsガイド「浅い」ネスト https://railsguides.jp/routing.html#%E3%80%8C%E6%B5%85%E3%81%84%E3%80%8D%E3%83%8D%E3%82%B9%E3%83%88  Railsのresourcesとresourceついて https://qiita.com/Atsushi_/items/bb22ce67d14ba1abafc5 Railsで超簡単API https://qiita.com/k-penguin-sato/items/adba7a1a1ecc3582a9c9
0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?