Devise路由映射错误:无法找到/hotels/9/users的映射
Let's break down what's causing this error and how to fix it step by step.
The Root Cause
Your current routes setup has a critical conflict: you're nesting devise_for :users inside the hotels resource. Devise expects its routes to follow a specific top-level structure, and nesting it under /hotels/:hotel_id confuses its routing mapper. When you try to access /hotels/9/users, Devise tries to match this path to one of its predefined mappings—and fails because it doesn't exist in its expected route schema.
Step 1: Correct Your Routes
First, move the Devise configuration to the top level of your routes file, and keep hotel-specific user actions as standard nested REST resources. Here's the fixed routes.rb:
Rails.application.routes.draw do # Keep Devise's core routes at the top level, pointing to your custom invitations controller devise_for :users, controllers: { invitations: 'users' } resources :hotels do # Define hotel-specific user actions as standard nested resources resources :users, only: [:index, :new, :create] end end
This setup separates Devise's core authentication flows from your hotel-specific user management. The /hotels/:hotel_id/users path will now route directly to your UsersController#index without triggering Devise's mapping checks.
Step 2: Tweak Your Controller Logic
Your UsersController is mostly set up correctly, but let's adjust one detail for consistency with common authorization practices (using Pundit):
def index @hotel = Hotel.find(params[:hotel_id]) @users = policy_scope(@hotel.users) # Run policy scope first authorize @users end
This ensures you're applying your authorization rules before fetching the final user list, which is the standard order for Pundit implementations.
Step 3: Verify the Fixed Routes
Run rails routes again, and you should see clean, standard mappings for your hotel-specific user routes:
hotel_users GET /hotels/:hotel_id/users(.:format) users#index POST /hotels/:hotel_id/users(.:format) users#create new_hotel_user GET /hotels/:hotel_id/users/new(.:format) users#new
These are regular REST routes, not Devise routes, so the "could not find devise mapping" error will no longer occur.
Why This Works
By moving devise_for :users to the top level, we let Devise handle its standard flows (login, password reset, invitations) using its expected route structure. The nested users resource under hotels handles your custom hotel-specific user management, which doesn't need to interact with Devise's routing system at all.
内容的提问来源于stack exchange,提问作者techquestion

