Пользователь с ролью администратора может иметь много отелей, но как администратор может пригласить пользователя только в один из своих отелей?

Контекст Я не могу понять следующее:

  • Между пользователем и отелем существует связь «многие ко многим» через таблицу соединений User_Hotel.
  • Пользователь, созданный с помощью devise, имеет роль администратора.
  • Пользователь с ролью администратора может создавать множество отелей.
  • Пользователь с ролью администратора должен иметь возможность приглашать других пользователей в определенный отель (например, не во все его отели). Я использую гем devise-invitable для отправки приглашений.

Проблемы Я настроил маршруты, модели и контроллер для пользователей/приглашений, но что-то пошло не так:

  1. так как мои параметры hotel_id не отправляются должным образом в мой приглашения_контроллер. См. сообщение об ошибке: Couldn't find Hotel without an ID. params sent: {"format"=>"109"}
  2. Я не уверен, должен ли / как я должен создавать связи между этим конкретным отелем и пользователем, который приглашен?

виды/отели/шоу

<%= link_to "invite new user", new_user_invitation_path(@hotel) %>

маршруты

Rails.application.routes.draw do
  devise_for :users, controllers: {
    invitations: 'users/invitations'
  }

  resources :hotels do
    resources :users
  end
end

модели

class User < ApplicationRecord
  has_many :user_hotels, dependent: :destroy
  has_many :hotels, through: :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

контроллеры/пользователи/приглашения

class Users::InvitationsController < Devise::InvitationsController
  def new
    @hotel = Hotel.find(params[:hotel_id])
    @user = User.new
    How to build the join table UserHotel when inviting?
  end
end

person techquestion    schedule 30.10.2019    source источник


Ответы (1)


IDK, если пользователь, приглашенный в отель, должен принять или нет.

При необходимости принять:

Вам нужна таблица для хранения приглашений, где вы будете хранить user a приглашение на user b на hotel a. Тогда вам нужны inviter_id, invited_id, hotel_id. Когда пользователь примет приглашение, вы добавите запись в свою промежуточную таблицу, касающуюся отеля и пользователя.

Другой способ - в вашей промежуточной таблице добавить флаг для управления тем, какие из них приняты, а какие еще нет, и добавить область действия по умолчанию для отношения, чтобы получить только принятые.

Если пользователь будет напрямую добавлен в отель:

Вам нужно только сделать:

@hotel = Hotel.find(params[:hotel_id])
@user = User.new
@user.hotels << @hotel
person facundo espinosa    schedule 30.10.2019
comment
Спасибо за развернутый отзыв. Я использую гем devise-invitable, поэтому я считаю, что гем делает это за меня. Я уже использую @hotel = Hotel.find(params[:hotel_id]), но получаю сообщение об ошибке Couldn't find Hotel without an ID. params sent: {"format"=>"109"} - person techquestion; 30.10.2019