Rails Active Record -Как смоделировать сценарий пользователя/профиля

У меня есть приложение rails, в котором есть три разных типа пользователей, и мне нужно, чтобы все они делились одной и той же общей информацией профиля. Однако каждый отдельный пользователь также имеет уникальные атрибуты. Я не уверен, как разделить разные поля.

  • Администратор (Администратор всего сайта)
  • Владелец (магазина/и т. д.)
  • Участник (, например член кооператива -оператор)

Я использую devise для аутентификации и cancan для авторизации. Поэтому у меня есть модель пользователя с набором ролей, которые можно применить к пользователю. Этот класс выглядит так:

class User < ActiveRecord::Base
  #... devise stuff omitted for brevity...

  # Roles association
  has_many :assignments
  has_many :roles, :through => :assignments

  # For cancan: https://github.com/ryanb/cancan/wiki/Separate-Role-Model
  def has_role?(role_sym)
    roles.any? { |r| r.name.underscore.to_sym == role_sym }
  end
end

У каждого пользователя есть профиль, который включает:

  • Имя и фамилию
  • Информация об адресе (город/улица/почтовый индекс/и т. д.)
  • Телефон

Я не хочу загрязнять Модель пользователя с этой информацией, поэтому я добавляю ее в модель профиля. Эта часть довольно проста. Это превращает модель пользователя во что-то вроде этого:

class User < ActiveRecord::Base
  #... devise stuff omitted for brevity...
  #... cancan stuff omitted for brevity... 
  has_one :profile
end

Дополнительные поля — это то место, где у меня есть некоторые непростые чувства по поводу того, как моделировать...

Если пользователь является администратором, у него будут уникальные поля, такие как:

  • admin _поле _a :строка
  • admin _поле _b :строка
  • и т. д.

Если пользователь является владельцем, у него будут уникальные поля...

  • полоса _API _ключ :строка
  • полоса _тест _API _ключ :строка
  • полоса _учетная запись _номер :строка
  • имеет _одно :хранилище #Ссылка AR на другую модель, которой нет у администратора и участника.

Если пользователь является участником, у него будет несколько дополнительных полей, таких как:

  • полоса _учетная запись _номер :строка
  • принадлежит _к :магазин #магазин, членом которого они являются
  • , имеет _много :примечание

...

, а модель магазина будет содержать _много членов, поэтому мы работаем с членами магазина.

Проблема связана с дополнительными полями. Я устанавливаю их как разные классы? Поместите их в другой В настоящее время я пробовал несколько разных способов настроить это.:

Один из способов — настроить модель пользователя как совокупный корень.

class User < ActiveRecord::Base
  #...

  # Roles association
  has_many :assignments
  has_many :roles, :through => :assignments

  # Profile and other object types
  has_one :profile
  has_one :admin
  has_one :owner
  has_one :member

  #...
end

Преимущество этого подхода в том, что модель пользователя является корнем и может получить доступ ко всему. Ошибка заключается в том, что если пользователь является «владельцем», то ссылки «admin» и «member» будут нулевыми (, а декартово значение других возможностей -admin, но не владелец или член и т. д. ).

Другой вариант, о котором я думал, заключался в том, чтобы каждый тип пользователя наследовался от модели User как таковой:

class User < ActiveRecord::Base
  #... other code removed for brevity
  has_one :profile
end

class Admin < User
  # admin fields
end

class Owner < User
  # owner fields
end

class Member < User
  # member fields
end

Проблема в том, что я загрязняю объект User всеми видами nil в таблице, где один тип не нужны значения из другого типа/и т.д. Просто кажется немного грязным, но я не уверен.

Другой вариант состоял в том, чтобы создать каждый тип учетной записи как корневой, но сделать пользователя дочерним объектом, как показано ниже.

class Admin
  has_one :user
  # admin fields go here. 
end

class Owner
  has_one :user
  # owner fields go here. 
end

class Member
  has_one :user
  # member fields go here. 
end

Проблема с вышеизложенным заключается в том, что я не уверен, как загрузить правильный класс после того, как пользователь войдет в систему. У меня будет его идентификатор пользователя _, и я смогу определить, какую роль он выполняет (из-за ассоциации ролей в пользовательской модели ), но я не уверен, как перейти от пользователя UP к корневому объекту. Методы? разное?

Заключение У меня есть несколько разных способов сделать это, но я не уверен, что такое правильный подход "rails". Как правильно смоделировать это в rails AR? (Серверная часть MySQL ). Если нет «правильного» подхода, что лучше из вышеперечисленного (Я также открыт для других идей ).

Спасибо!

9
задан Donn Felker 22 March 2012 в 21:12
поделиться