0

简短说明:

我寻求架构建议和帮助,以在单个应用程序中实现多个设计模型。

更详细的解释:

我的应用程序需要执行以下行为:

有 3 种类型的用户(Partner, Attendee, Speaker),它们有一些常见的字段和一些独特的字段(此外,这些字段可能有不同的权限,即Attendee必须有用户名,而Speaker可能有,但他们不必填写这个字段在)。而且,不同的用户模型必须与数据库中的其他表有不同的关联。

用户需要能够通过单一登录表单登录,但注册表应该不同。

所以,我的第一个想法是我应该使用Punditordeclarative_authorization或其他东西来划分用户,但是用户在应用程序中并没有真正的不同角色(即权限),他们有不同的行为,他们可能会看到不同的内容和东西,所以我继续思考。

我的第二个想法是实现 STI,在阅读了几篇关于它的文章后,我尝试在代码中实现。

我通过执行和运行后生成了一个设计User模型,对于其他两个用户也是如此。rails g devise Userrails g model Attendee

然后,我继承了我的模型User

class Attendee < User
end

我的User迁移如下所示:

create_table :users do |t|
  t.string :first_name
  t.string :last_name
  t.string :type

  # Devise stuff ...
  ..................

  t.timestamps null: false
end

其他迁移是这样的:

create_table :attendees do |t|
  t.string :username
  t.string :company_name
  t.boolean :subscription

  t.timestamps null: false
end

现在我意识到创建单独的表是错误的。我必须将所有可能的字段放入User表中,对吗?因为现在当我尝试创建任何新的AttendeeorSpeakerPartnerin 时rails console,所有这三个模型都具有完全相同的字段,即User模型具有的字段。

但是,如果我在User模型中添加所有可能的字段,我将如何对字段存在进行验证?


我在这里阅读了很多关于 SO 的文章和问题,但仍然无法真正理解如何实现所有这些。

无论如何,这是做我需要的正确方法吗?

谁能详细解释一下我应该如何从头到尾实现这种行为和功能,以及在实现模型后我应该如何使用它们?

PS:这是我的迁移历史和整个github 存储库


更新

想起另一个阻止我进行角色分离的问题:

我应该如何使用不同的注册表单注册不同的用户?不同的路线?我不能让用户从组合框中选择他们的角色。

4

1 回答 1

1

您可以根据角色创建条件验证规则,但首先需要解决此问题的是在 new/edit User 表单中,仅根据角色动态显示允许的字段:

class User < ActiveRecord::Base
  validates :company, presence: true, if: :is_company?

  def is_company
   # check for the role
   self.role == 'company'
  end
end

更新:您可以将一个额外的参数传递给同一个注册表单,并使用它来区分您显示的表单类型。这是最好的方式。您还可以在 UserController -> def register_user、def register_company、def register_xxxx 中创建单独的方法

于 2015-11-19T09:11:09.430 回答