Модели 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

Ура!

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