Рельсы: полиморфные или нет? - PullRequest
2 голосов
/ 10 июля 2009

С учетом следующих ресурсов с соответствующими отношениями:

Site 
 has_many :page
 has_many :groups
 has_many :projects

Group
 belongs_to :site
 has_many :pages

Project
 belongs_to :site
 has_many :pages

Хорошо ли сделать модель Page полиморфной или оставить отдельные внешние ключи?

**Scenario 1 (Polymorphic)**
Page
 pageable_id
 pageable_type
 title
 body
 ....
 ....

**Scenario 2 (Non Polymorphic)**
Page 
 site_id (always filled)
 group_id (may be empty)
 project_id (may be empty)
 title
 body
 ....
 ....

**Scenario 3 (Combination)**
Page
 site_id
 pageable_id (may be empty, if page belongs only to site)
 pageable_type (may be empty, if page belongs only to site)
 title
 body
 .....
 .....

Какой из трех сценариев вы бы предпочли? И почему (с точки зрения эффективности и т.д ..)

Примечание: По моим представлениям, я буду обходить все возможные связи страницы, чтобы показать соответствующие ссылки (например: если страница принадлежит группе, я показываю ссылку обратно в группу , ...)

1 Ответ

0 голосов
/ 11 июля 2009

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

Это оставило бы только сценарий 1 ...

Если вы хотите иметь возможность создавать site.pages и получать все страницы, принадлежащие этому сайту (также страницы, принадлежащие группе, принадлежащей этому сайту), вы, конечно, можете написать свою собственную функцию:

class Site
  def all_pages
    Page.find_by_sql(["SELECT p.* FROM pages p, sites s, groups g, projects j WHERE (p.pageable_type='Site' AND p.pageable_id=?) OR (p.pageable_type='Group' AND p.pageable_id=g.id AND g.site_id=?) OR (p.pageable_type='Project' AND p.pageable_id=j.id AND j.site_id=?, self.id, self.id, self.id])
  end
end

(Кроме того, я бы назвал столбец pageable_id «parent_id» и pageable_type «parent_type» в этом случае. Мне это кажется более логичным ...)

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