3

我正在尝试在 Devise 中创建多个模型(使用 Ruby 2.0、Rails 4)。我搜索过 Stack Overflow 并尝试过 Google,但大多数人最终使用继承或 CanCan。

问题是我需要两种完全不同的模型才能以两种完全不同的方式注册和使用我的网站 - 一种使用电子邮件或用户名登录,并且具有各种管理能力(例如查看 MobileUser 的图表用法等)。另一个只能从移动设备访问,使用电话号码登录,并且界面更简单。

我尝试为两者('rails g devise WebUser'和'rails g devise MobileUser')运行设计。我现在有两者的表和列,但只有 WebUser 的路由和模型。我尝试为 MobileUser 手动添加路由和模型,但没有任何效果 - 模型未连接到表,路由产生运行时错误('WebUser 不响应'设计'方法)。

我读过的所有内容都表明我可以让 Devise 在我的一个网站上为两个模型工作——我该如何实现呢?

我的路线:

Mailer::Application.routes.draw do
  devise_for :web_users
  # devise_for :mobile_users (doesn't work, so it is commented out)

  resources 'web_users', only: [:show, :index]
  resources 'mobile_users', only: [:show, :index]

  root 'static_pages#home'

  match '/contact',  to: 'static_pages#contact',  via: 'get'
  match '/faq',      to: 'static_pages#faq',      via: 'get'
end
4

2 回答 2

5

我知道这是一个非常古老的问题,但也许在 2019 年,Devise 支持devise_group对现在的人会有帮助。

Thins 使得使用多个 Devise 模型变得非常容易。我有三种不同的设计模型,如下所示:

用户.rb

class User < ApplicationRecord
    has_many :messages

    # Include default devise modules. Others available are:
    # :confirmable, :lockable, :timeoutable and :omniauthable
    devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
end

组织者.rb

class Organizer < ApplicationRecord
    has_one :organizer_profile, dependent: :destroy, autosave: true, inverse_of: :organizer
    has_many :brochures, dependent: :destroy
    has_many :messages, as: :messageable

    # Include default devise modules. Others available are:
    # :confirmable, :lockable, :timeoutable and :omniauthable
    devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable
end

赞助商.rb

class Sponsor < ApplicationRecord
    has_one :sponsor_profile, dependent: :destroy, autosave: true, inverse_of: :sponsor
    has_many :sponsorings
    has_many :brochures, through: :sponsorings

    # Include default devise modules. Others available are:
    # :confirmable, :lockable, :timeoutable and :omniauthable
    devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable

    scope :approved, -> { where(approved: true) }

    # Allow saving of attributes on associated records through the parent,
    # :autosave option is automatically enabled on every association
    accepts_nested_attributes_for :sponsor_profile
end

路线.rb

Rails.application.routes.draw do
    # Deviseable resources
    devise_for :organizers, controllers: {registrations: "organizers/registrations"}
    devise_for :sponsors, controllers: {registrations: "sponsors/registrations"}
    devise_for :users

    root "welcome#index"
end

现在我不能用同样的authenticate_user!user_signed_in?甚至current_user。那么现在,我如何知道是否有用户登录?我们可能需要做类似user_signed_in? || organizer_signed_in? || sponsor_signed_in?的事情,但重复代码太多了。

由于devise_group选项,我们可以简化此工作流程!

在你application_controller.rb添加这个:

class ApplicationController < ActionController::Base
    # Devise working with multiple models.
    # Define authentication filters and accessor helpers for a group of mappings.
    devise_group :member, contains: [:organizer, :sponsor, :user]

    private

    def pundit_user
        # Make Pundit to use whichever Devise model [Organizer, Sponsor, User] as the 'current_user'
        # Just by using the offered helper method from Devise, 'devise_group' feature
        current_member
    end
end

现在您可以使用通用助手authenticate_member!member_signed_in?甚至current_member在需要时验证任何设计用户。或者,您仍然可以像往常一样为每种类型的 Devise 用户提供用户分离的帮助程序。

希望它对某人有用!

于 2019-09-03T18:14:20.980 回答
0

以下摘录来自设计 gem 自述文件:

使用以下方法生成模型:

rails generate devise MODEL

使用以下定义自定义视图:

rails generate devise:views MODELS

使用以下方法生成自定义控制器:

rails generate devise:controllers [scope]

然后在你的路线中

devise_for :MODELS, controllers: { sessions: "MODELS/sessions" }

我一直在使用具有多个模型的设计,使用这些步骤没有任何困难......

于 2015-04-15T17:41:22.283 回答