Несколько моделей Devise с уникальными атрибутами

Краткое объяснение:

Я ищу архитектурный совет и помощь в реализации нескольких моделей Devise в одном приложении.

Более подробное объяснение:

Мое приложение должно выполнить следующее поведение:

Есть 3 типа пользователей (Partner, Attendee, Speaker), которые имеют некоторые общие поля и некоторые уникальные (кроме того, поля могут иметь разные разрешения, т.е. Attendee должен иметь имя пользователя, тогда как Speaker может быть, но они не обязательно должны заполнять это поле). И более того, разные пользовательские модели должны иметь разные ассоциации с другими таблицами в БД.

Пользователи должны иметь возможность войти через единую форму входа, но формы регистрации должны отличаться.

Итак, моей первой мыслью было то, что я должен разделить пользователей по ролям, используя Pundit или же declarative_authorization или что-то в этом роде, но у пользователей на самом деле нет разных ролей (т.е. разрешений) в приложении, они скорее ведут себя по-разному, они могут видеть разный контент и прочее, поэтому я продолжил думать.

Второй момент - реализация STI, и после прочтения нескольких статей об этом я попытался сделать это в коде.

Я создал Devise User модель, делая rails g devise User и после этого побежал rails 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 таблица, это правильно? Потому что сейчас, когда я пытаюсь создать любой новый Attendee или же Speaker или же Partner в rails consoleвсе эти три модели имеют одинаковые поля, User модель имеет.

Но если я добавлю все возможные поля в User модель, как бы я проверил наличие полей?


Я прочитал довольно много статей и вопросов здесь о SO, но все еще не могу понять, как все это реализовать.

В любом случае, это правильный способ сделать то, что мне нужно?

Может ли кто-нибудь подробно объяснить мне, как я должен реализовывать такое поведение и функциональность от начала до конца, и как я должен работать с моделями после их реализации?

PS: вот история моих миграций и всего репозитория github


Обновить

Вспомнил еще одну проблему, которая помешала мне просто разделить роли:

Как мне зарегистрировать разных пользователей с разными формами регистрации? Разные маршруты? Я не могу заставить пользователя выбрать свою роль из списка.

1 ответ

Решение

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

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

Другие вопросы по тегам