Несколько моделей 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