【问题标题】:How to nest devise_invitable such that a user can be invited to only 1 hotel如何嵌套 devise_invitable 以便用户只能被邀请到 1 家酒店
【发布时间】:2019-11-05 10:09:32
【问题描述】:

目标

我想让 user.admin 使用 devise_invite gem 仅邀请用户到其中一家酒店。

=> UserHotel 通过连接表 UserHotel 连接。

问题

我开始怀疑我设置 devise(_invitable) 的方式。以我目前的设置方式,我无法创建 user_hotel Join_table 和/或将特定的酒店参数添加到受邀用户,请参阅下面的输出以进行检查:

  • 控制器 >> @user.hotels => #<ActiveRecord::Associations::CollectionProxy []>

  • 控制台:

pry(main)> User.invitation_not_accepted.last.hotels
  User Load (0.6ms)  SELECT  "users".* FROM "users" WHERE "users"."invitation_token" IS NOT NULL AND "users"."invitation_accepted_at" IS NULL ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]
  Hotel Load (0.4ms)  SELECT "hotels".* FROM "hotels" INNER JOIN "user_hotels" ON "hotels"."id" = "user_hotels"."hotel_id" WHERE "user_hotels"."user_id" = $1  [["user_id", 49]]
=> []

更新

问题似乎在于用户和酒店之间的多对多关系。当我在hotel.user.new 之后打破我的控制器“新”操作并对其进行测试时,我发现了以下内容:

  • >> @user.hotels => #<ActiveRecord::Associations::CollectionProxy []>
  • >> @hotel.users => #<ActiveRecord::Associations::CollectionProxy [#<User id: 2, email: "test@hotmail.com", created_at: "2019-11-05 14:17:46", updated_at: "2019-11-05 15:04:22", role: "admin">, #<User id: nil, email: "", created_at: nil, updated_at: nil, role: "admin">]>

注意 我使用设计设置用户,以便我的用户控制器构建为:

  • users/confirmations_controller.rb
  • users/invitations_controller.rb
  • users/omniauth_callbacks_controller.rb
  • users/password_controller.rb
  • users/registrations_controller.rb
  • users/sessions_controller.rb
  • users/unlocks_controller.rb

代码

路线

Rails.application.routes.draw do

  devise_for :users

  resources :hotels do
devise_for :users, :controllers => { :invitations => 'users/invitations' }
  end
end

型号

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

查看/酒店/节目

&lt;%= link_to "invite new user", new_user_hotel_invitation_path(@hotel)%&gt;

控制器/用户/invitations_controller.rb

class Users::InvitationsController < Devise::InvitationsController
  def new
    @hotel = Hotel.find(params[:hotel_id])
    @user = @hotel.users.new
  end

  def create
    @hotel = Hotel.find(params[:hotel_id])
    @user = @hotel.users.new(hotel_user_params)
    @user.invite!
  end

  private
  def hotel_user_params
    params.require(:user).permit(:email, :role,
      hotel_users_attributes: [:hotel_id])
  end
end

意见/邀请/new.html.erb

<h2><%= t "devise.invitations.new.header" %></h2>

<%= simple_form_for(resource, as: resource_name, url: user_hotel_invitation_path(@hotel), html: { method: :post }) do |f| %>  <%= f.error_notification %>

  <% resource.class.invite_key_fields.each do |field| -%>
    <div class="form-inputs">
      <%= f.input field %>
    </div>
  <% end -%>

      <%= f.input :role, collection: [:owner, :admin, :employee] %>
  <div class="form-actions">
    <%= f.button :submit, t("devise.invitations.new.submit_button") %>
  </div>
<% end %>

【问题讨论】:

    标签: ruby-on-rails devise devise-invitable


    【解决方案1】:

    你检查了吗:

    invitation_limit: 用户可以发送的邀请数。这 默认值 nil 表示用户可以发送尽可能多的邀请 想要,任何用户都没有限制,invitation_limit 列没有 用过的。设置为 0 表示他们无法发送邀请。一个设置 n > 0 表示他们可以发送 n 个邀请。您可以更改邀请限制 某些用户的列,以便他们可以发送或多或少的邀请,甚至 全局邀请限制 = 0。

    此外,查看有关 gem 的更多详细信息以获取更多选项将是非常明智的举措:https://github.com/scambra/devise_invitable

    【讨论】:

    • 感谢您的评论。我确实检查了这一点,但我仍然应用默认的 nil,所以应该可以发送邀请。
    • @techquestion,据我了解,您应该将值设置为 1 以将邀请限制为一次。
    • 再次感谢,我至少应该对其进行测试以确定;)刚刚检查过,但我仍然得到相同的响应。
    【解决方案2】:

    我有一些工作,即使很难,我不确定这是否是最好的方法(阅读:我非常怀疑)。

    class Users::InvitationsController < Devise::InvitationsController
      def new
        @hotel = Hotel.find(params[:hotel_id])
        @user = @hotel.users.new
        @user.hotels << @hotel
      end
    
      def create
        @hotel = Hotel.find(params[:hotel_id])
        @user = @hotel.users.new(hotel_user_params)
        @user.hotels << @hotel
        @user.invite!
      end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多