Полиморфная ассоциация для многотипной регистрации в рельсах
Я использую devise для аутентификации моего приложения. У меня есть модель User
, которая является моделью входа/выхода.
Функциональность заключается в том, что когда клиент, то есть пользователь, регистрируется, он будет заполнять обязательную страницу профиля пользователя. Все работало нормально, используя разработки.
Теперь у меня есть новый функционал, пользователь может быть разных типов( допустим A
, B
,C
)
Если пользователь имеет тип A
, то он должен следовать тому же процессу регистрации и та же страница профиля.
Если пользователь имеет тип B
, то экран регистрации отличается и ожидает подтверждения от администратора. Различные изменения для типа C
тоже.
Все разные типы имеют разные страницы профиля, и поля различаются.
Поэтому я решил иметь полиморфную ассоциацию, и вот как выглядят мои модели
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me
belongs_to :user_type, :polymorphic => true
end
class A
has_one :user, :as => :user_type
end
class B
has_one :user, :as => :user_type
end
class C
has_one :user, :as => :user_type
end
Я просто хочу знать, является ли это правильным способом реализации сценария или есть лучший способ реализовать это?
2 ответа:
Вам нужна колонка Rails' magic
type
.# user.rb class User < ActiveRecord::Base # create_table 'users' do |t| # t.string :name # t.string :type # end end # user_a.rb class UserA < User end # user_b.rb class UserB < User end # user_c.rb class UserC < User end
UserA.create(name: "bricker") user_a = User.where(type: "UserA").first same_user_a = UserA.all.first user_a == same_user_a #=> true user_a.class #=> UserA user_a.is_a? User #=> true
Обновить
class UserLogin < ActiveRecord::Base # create_table :user_logins do |t| # t.integer :user_id # t.string :user_type # t.string :login # t.string :encrypted_password # end # devise ... belongs_to :user, polymorphic: true end class User < ActiveRecord::Base self.abstract_class = true has_one :user_login, as: :user end class Admin < User # create_table :admins do |t| # t.integer :user_login_id # t.string :admin_name # end end class Moderator < User # create_table :moderators do |t| # t.integer :user_login_id # t.string :moderator_name # end end
Я уже занимался этим раньше
Я бы настоятельно рекомендовал использовать неполиморфные отдельные модели и делиться общей функциональностью с миксинами.
У меня была та же установка, которую вы описали, и мне пришлось ее рефакторировать позже, так как она стала действительно раздутой и сложной по мере разработки проекта