Context
I implemented devise & devise_invitable where a user.admin can have many hotels and subsequently can invite a user to s specific hotel.
Issue
I would like to generate an index page of all the users belonging to a hotel (whether they accepted the invitation or not). Unfortunately, I get the following error message:
Could not find devise mapping for path "/hotels/9/users".
This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do get "/some/route" => "some_devise_controller" end
2) You are testing a Devise controller bypassing the router.
If so, you can explicitly tell Devise which mapping to use:
@request.env["devise.mapping"] = Devise.mappings[:user]
Code
routes
Rails.application.routes.draw do
devise_for :users
resources :hotels do
devise_for :users, :controllers => { :invitations => 'users' }
resources :users, only: [:index]
end
end
rails routes
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) devise_invitable/registrations#cancel
new_user_registration GET /users/sign_up(.:format) devise_invitable/registrations#new
edit_user_registration GET /users/edit(.:format) devise_invitable/registrations#edit
user_registration PATCH /users(.:format) devise_invitable/registrations#update
PUT /users(.:format) devise_invitable/registrations#update
DELETE /users(.:format) devise_invitable/registrations#destroy
POST /users(.:format) devise_invitable/registrations#create
accept_user_invitation GET /users/invitation/accept(.:format) devise/invitations#edit
remove_user_invitation GET /users/invitation/remove(.:format) devise/invitations#destroy
new_user_invitation GET /users/invitation/new(.:format) devise/invitations#new
user_invitation PATCH /users/invitation(.:format) devise/invitations#update
PUT /users/invitation(.:format) devise/invitations#update
POST /users/invitation(.:format) devise/invitations#create
new_user_hotel_session GET /users/hotels/:hotel_id/sign_in(.:format) devise/sessions#new
user_hotel_session POST /users/hotels/:hotel_id/sign_in(.:format) devise/sessions#create
destroy_user_hotel_session DELETE /users/hotels/:hotel_id/sign_out(.:format) devise/sessions#destroy
new_user_hotel_password GET /users/hotels/:hotel_id/password/new(.:format) devise/passwords#new
edit_user_hotel_password GET /users/hotels/:hotel_id/password/edit(.:format) devise/passwords#edit
user_hotel_password PATCH /users/hotels/:hotel_id/password(.:format) devise/passwords#update
PUT /users/hotels/:hotel_id/password(.:format) devise/passwords#update
POST /users/hotels/:hotel_id/password(.:format) devise/passwords#create
cancel_user_hotel_registration GET /users/hotels/:hotel_id/cancel(.:format) devise_invitable/registrations#cancel
new_user_hotel_registration GET /users/hotels/:hotel_id/sign_up(.:format) devise_invitable/registrations#new
edit_user_hotel_registration GET /users/hotels/:hotel_id/edit(.:format) devise_invitable/registrations#edit
user_hotel_registration PATCH /users/hotels/:hotel_id(.:format) devise_invitable/registrations#update
PUT /users/hotels/:hotel_id(.:format) devise_invitable/registrations#update
DELETE /users/hotels/:hotel_id(.:format) devise_invitable/registrations#destroy
POST /users/hotels/:hotel_id(.:format) devise_invitable/registrations#create
accept_user_hotel_invitation GET /users/hotels/:hotel_id/invitation/accept(.:format) users#edit
remove_user_hotel_invitation GET /users/hotels/:hotel_id/invitation/remove(.:format) users#destroy
new_user_hotel_invitation GET /users/hotels/:hotel_id/invitation/new(.:format) users#new
user_hotel_invitation PATCH /users/hotels/:hotel_id/invitation(.:format) users#update
PUT /users/hotels/:hotel_id/invitation(.:format) users#update
POST /users/hotels/:hotel_id/invitation(.:format) users#create
hotel_users GET /hotels/:hotel_id/users(.:format) users#index
models
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
has_many :user_hotels, dependent: :destroy
has_many :hotels, through: :user_hotels
accepts_nested_attributes_for :user_hotels
enum role: [:owner, :admin, :employee]
after_initialize :set_default_role, :if => :new_record?
def set_default_role
self.role ||= :admin
end
devise :invitable, :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :invitable
end
class UserHotel < ApplicationRecord
belongs_to :hotel
belongs_to :user
end
class Hotel < ApplicationRecord
has_many :user_hotels, dependent: :destroy
has_many :users, through: :user_hotels
accepts_nested_attributes_for :users, allow_destroy: true, reject_if: ->(attrs) { attrs['email'].blank? || attrs['role'].blank?}
end
controller
class UsersController < Devise::InvitationsController
after_action :verify_authorized, except: :index
def new
@hotel = Hotel.find(params[:hotel_id])
@user = @hotel.users.new
authorize @user
end
def create
@hotel = Hotel.find(params[:hotel_id])
@user = @hotel.users.new(hotel_user_params)
@user.user_hotels.build(hotel: @hotel)
authorize @user
if @user.invite!
redirect_to root_path
else
render 'new'
end
end
def index
@hotel = Hotel.find(params[:hotel_id])
@users = @hotel.users
authorize @users
@users = policy_scope(@users)
end
private
def hotel_user_params
params.require(:user).permit(:email, :role,
user_hotels_attributes: [:hotel_id,
hotel_attributes:[:name, :slug, :description, :street, :street_number, :zipcode, :city, :country, :email, :phone, :website, :vat_number, :currency, :photo, :test_modus, :default_vat, :price_notation, :paytime, :billing_id, :default_hotel_language, :default_age_table]])
end
end
I fixed my issue, by creating a seperate devise_invitable controller. Thereby using the users_controller for the index action.