Модели Rails: для многочисленных ролей, моделей с несколькими пользователями с дополнительными под ролями - правильный дизайн?
Я пишу свое первое приложение Ruby On Rails - веб-сайт для закрытого жилого сообщества.
Зона сообщества состоит из пустых участков с одним или несколькими домами на застроенном участке. Участки будут иметь только одного владельца, но у нескольких домов на участке могут быть разные Владельцы. Существуют избранные офисные владельцы с разными ролями (в ассоциации жильцов) и сотрудники по управлению имуществом и т. Д. В конечном итоге будут созданы группы пользователей (только владельцы или только арендаторы или смешанные и т. Д.).
Владелец и Арендатор имеют тенденцию быть совершенно разными, поэтому я держу их в качестве отдельных классов. Точно так же члены их семей, как правило, тоже разные - классы OwnerFamilyMember и TenantFamilyMember.
Моим первым проектом было создание модели "Пользователь", "Роль и назначение" - ролей стало слишком много. Поэтому я делю пользовательскую модель, как указано выше (я не хочу использовать ИППП или полиморфные ассоциации, я хотел бы сначала сделать это правильно).
Модельные классы:
# All classes below inherit from ActiveRecord::Base, removed other attributes for compactness
class Owner
has_many :plots
has_many :houses
has_many :owner_family_members
end
class Tenant
belongs_to :house # declare house_id in table
has_many :tenant_family_members
end
class Staff ...
class Plot
belongs_to :owner # declare owner_id in table
end
class House
belongs_to :owner # declare owner_id in table
end
class OwnerFamilyMember
belongs_to :owner # declare owner_id in table
end
class TenantFamilyMember
belongs_to :tenant # declare tenant_id in table
end
- Арендаторы или Владельцы проживают в домах.
- FamilyMembers Владельцы или Арендаторы будут участвовать в сообществе, но они зависят от основного Владельца или Арендатора для определенных привилегированных действий
Я понимаю, что с этим дизайном различные модели пользователей имеют неявные роли и могут иметь дополнительные под роли, если это необходимо - владелец может быть казначеем для ассоциации жильцов, арендатор может возглавлять группу по сохранению воды и т. Д. Я ожидаю, что число роли, чтобы развиваться дальше, и, следовательно, я думаю, что лучше сохранить несколько моделей пользователей.
Я на правильном пути? Я путаю неправильные вещи в этом рецепте? Стремятся услышать любые отзывы, концептуальные или конкретные реализации, которые могут помочь мне лучше понять это.
Я понимаю концепции БД, программирование ОО, но я новичок в разработке БД на уровне производства или в приложениях RoR. Спасибо за чтение этого длинного поста. - Джаявант
1 ответ
Добро пожаловать в сообщество Rails! Вам здесь понравится.
Прежде всего, вам не нужно уклоняться от ИППП или полиморфных ассоциаций, они являются весьма ценными инструментами в мире Rails. Ваша стратегия User/Role/Assignment (объединяющая таблица) кажется разумной, чтобы иметь дело с хорошим стандартизированным подходом аутентификации и авторизации на основе ролей. Я бы держал модель User достаточно отделенной от другой логики вашего приложения и авторизовал бы сделки, используя библиотеку CanCan Райана Бейтса, и проводил бы аутентификацию через библиотеку Devise от Plataforma.
Теперь у вас есть хорошая настройка аутентификации / авторизации, которая не зависит от множества различных моделей User/Admin/GuyWhoAuthenticates, а приложение намного проще. Пример:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
...
if user.has_role? 'plot_owner'
can :manage, Plot, user_id: user.id
end
...
end
end
class User < ActiveRecord::Base
has_many :assignments
has_many :roles, through: :assignments
...
def has_role? role
roles.where(label: role)
end
...
end
Что касается других моделей, хорошее эмпирическое правило таково: какую логику они разделяют? Если они имеют одинаковые атрибуты, разделяют большое количество логики приложения и концептуально похожи (например, являются членами семьи), то я бы пошел с STI / полиморфными ассоциациями. Если нет, вы можете извлечь общую логику в отдельный модуль и включить ее в обе модели.
Так как вы новичок в мире Rails, я также настоятельно рекомендую вам проверить Railscasts и Peepcode, два замечательных скринкаст-сайта, которые позволят вам мгновенно превратить приложения Rails в босса:D
Ура!