Модели Rails: для многочисленных ролей несколько пользовательских моделей с дополнительными подролями — правильный дизайн?

Я пишу свое первое приложение Ruby On Rails — веб-сайт для закрытого жилого комплекса.

Общественная территория состоит из пустых участков с одним или несколькими домами на застроенном участке. У участков будет только один владелец, но несколько домов на участке могут иметь разных владельцев. Существуют избранные должностные лица с разными ролями (в ассоциации жильцов), сотрудники по управлению имуществом и т. д. В конечном итоге появятся группы пользователей (только владельцы или только арендаторы или смешанные и т. д.).

Владелец и арендатор, как правило, очень разные, поэтому я сохранил их как отдельные классы. Точно так же члены их семей, как правило, тоже различаются — классы OwnerFamilyMember и TenantFamilyMember.

Мой первый проект состоял в том, чтобы иметь одного пользователя, роль и модель назначения — ролей стало слишком много. Следовательно, я разделяю пользовательскую модель, как указано выше (я не хочу использовать STI или полиморфные ассоциации, я хотел бы сначала сделать это правильно).

Классы моделей:

# 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
  • Арендаторы или владельцы проживают в домах.
  • Члены семьи владельцев или арендаторов будут участвовать в сообществе, но они зависят от основного владельца или арендатора в отношении определенных привилегированных действий.

Я понимаю, что при таком дизайне разные модели пользователей имеют неявные роли и могут иметь дополнительные подроли, если это необходимо — владелец может быть казначеем ассоциации жильцов, арендатор может возглавлять группу по сохранению воды и т. д. Я ожидаю, что количество роли для дальнейшего развития, и поэтому я думаю, что лучше сохранить несколько пользовательских моделей.

Я на правильном пути? Я смешиваю неправильные вещи в этом рецепте? С нетерпением жду любых отзывов, концептуальных или специфичных для реализации, которые могут помочь мне лучше понять это.

Я понимаю концепции БД, объектно-ориентированное программирование, но я новичок в проектировании БД на производственном уровне или в приложениях RoR. Спасибо, что прочитали этот длинный пост. - Джаявант


person Jayawanth    schedule 18.01.2013    source источник


Ответы (1)


Добро пожаловать в сообщество Rails! Вам здесь понравится.

Прежде всего, вам не нужно избегать STI или полиморфных ассоциаций, они являются весьма ценными инструментами в мире Rails. Ваша стратегия User/Role/Assignment (join table) кажется разумной для работы с хорошей нормализованной аутентификацией и подходом авторизации на основе ролей. Я бы отделил модель User от остальной логики вашего приложения и авторизовал бы сделку, используя CanCan Райана Бейтса. библиотеку и пройти аутентификацию с помощью библиотеки Plataforma Devise.

Теперь у вас есть хорошая настройка аутентификации/авторизации, которая не зависит от множества различных моделей 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

Ваше здоровье!

person marcelowiermann    schedule 18.01.2013
comment
Марсель, спасибо за подробный ответ. Я видел рельсовые передачи Райана Бейта, круто! Я не знал о Peepcode, проверю. Ваши комментарии о модуле помогли мне лучше понять их значение. Возможно, я переоценил свои классы, ожидая слишком большого расхождения подобных классов в будущем. Я думаю, мне нужно быть осторожным с чрезмерным проектированием. - person Jayawanth; 19.01.2013