【问题标题】:Multiple Models in Devise设计中的多个模型
【发布时间】:2013-10-10 21:40:13
【问题描述】:

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

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

我尝试为两者运行 Devise('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

【问题讨论】:

  • 听起来很头疼。其中一个是全能的管理员,还是这些真正反映了不同的子集?
  • 这是两个不同的子集。类似于在 MailChimp 中,公司发送电子邮件,查看图表,表明谁收到了电子邮件,可以管理他们发送给谁,等等......但收件人只能查看电子邮件 - 没有控件,没有其他页面,什么都没有。除了我的,两者都必须登录 - WebUser 使用电子邮件,MobileUser 使用电话号码。
  • 你能显示你的路线吗?我将设计用于多个模型而没有问题,所以我要么误解了您的目标,要么需要更多信息来提供建议。
  • 添加到我原来的帖子中
  • 您的目标是拥有 2 个单独的登录页面,每个模型 1 个?

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


【解决方案1】:

我知道这是一个非常古老的问题,但也许它会在 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

Organizer.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

Sponsor.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

routes.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 用户。或者,您仍然可以像往常一样为每种类型的 Devise 用户提供用户分离的帮助程序。

希望它对某人有用!

【讨论】:

  • 我不知道设计组,这正是我要找的。另请注意,您可以调用“current_members”(复数)来获取当前在这些模型中登录您的会话的所有成员。
  • @TimBrandes 嘿!这对于 current_members 复数来说是一个很好的追赶。但我不知道它是如何有用的,不确定使用这个助手的场景。 ?
  • 我有一个上传模型。上传可以属于管理员、员工或合作伙伴,并且可以对他们每个人拥有访问权限。每个人都有自己的设计模型。在检查是否可以访问上传时, current_members 方法会派上用场,以检查 current_members 是否包含允许的访问控制设计模型之一!可能比检查是否 admin_signed_in 更好? || employee_signed_in?, ...
  • 是的,这听起来像是一种可能的情况,但我不确定,也许它也可以由 Pundit 或 CanCanCan 处理。不过谢谢分享!
  • 是的,如果您使用单独的库进行授权,那么我也会这样做。另一个用例是由多个设计模型共享的公共门户。通过检查 current_members,只有在任何成员登录时才会显示消息。
【解决方案2】:

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

使用以下方法生成您的模型:

rails generate devise MODEL

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

rails generate devise:views MODELS

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

rails generate devise:controllers [scope]

然后在你的路线中

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    • 2012-12-13
    相关资源
    最近更新 更多