2013-12-02 5 views
0

У меня есть две модели, статьи и документы. Каждый из них нуждается в редакторе, т. Е. Содержит элемент содержимого статьи или документа. Полиморфная ассоциация имеет смысл.Имеет ли смысл 1-1 полиморфная ассоциация?

Статья

class Article < ActiveRecord::Base 
    has_one :editor, :as => :editable 
end 

Документ

class Document < ActiveRecord::Base 
    has_one :editor, :as => :editable 
end 

Editor

class Editor < ActiveRecord::Base 
    belongs_to :editable, :polymorphic => true 
end 

модель Редактор содержит следующие атрибуты:

содержание, editable_id, editab le_type (название модели, то есть статья или документ)

Все это прекрасно работает, но мне оно нужно?

Если я хочу получить доступ к телу контента для данной статьи, могу ли я просто не просто получить идентификатор поля редактора так?

@article = Article.find(params[:id]) 
@editor_id = @article.editor.id 

и выполнить мой редактор, найти на этом.

В этом случае я не вижу преимущества взаимно однозначной полиморфной взаимосвязи. Может ли кто-нибудь настроить меня прямо?

+0

editable_id не уникален ... Я бы хотел, чтобы вы могли скрыть глупые вопросы о SO! –

ответ

1

Во-первых, за очень конкретный вопрос о том, почему вы не можете выполнять следующие из полиморфного отношений:

@article = Article.find (Params [: ид])

@ editor_id = @ article.editor.id

Вся причина работы @ article.editor.id связана с полиморфными отношениями. Это будет что-то на линии:

  • У вас есть HAS_ONE: редактор, который означает, что @ article.editor = это редактор модель, основанная на это редактируемые поля
  • Теперь, когда вы нашли этот редактор модель вот это идентификатор

Если вы вытащили has_one, он перестанет работать. Кроме того, вам не нужно делать находку вообще, потому что это также верно:

@article = Article.find (PARAMS [: идентификатор])

@editor = @ article.editor

Нет для более широкого вопроса о том, есть ли способ установить это, используя полиморфные вообще.

Чтобы сделать все как можно более простым, вы можете просто поместить поля содержимого в документ и статью.Это имело бы смысл, если:

  • Вы всегда будете использовать поле контента, так что вы не занимаете пространство базы данных для ничего

  • Там нет специального кода, проверки правильности, и т.д., который идет с содержанием и затем повторяется в двух местах.

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

  • Редактора упоминаются в нескольких местах, но нет ничего в таблице, чтобы сказать вам, кто использует какой столбец. Чтобы часто «читать» и «порт» базы данных, я хотел бы, чтобы это было хорошее будущее. (Это не проблема в тех случаях, когда вы не будете использовать полиморфизм, потому что знаете, что все элементы в этой таблице могут быть связаны только с одной таблицей.)

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

Так что возвращает нас обратно к оригиналу настроить. Полиморфные отношения делают несколько вещей:

  • проясняет в базе данных, которые каждая строка принадлежит
  • Позволяют сделать другую модель есть и редактор только с кодом и изменениями не базы данных
  • Сохраняют все функциональные возможности специфичный для содержимого редактора в одном хорошем месте

Итак, да, я думаю, что один-на-один полиморфный имеет смысл. Это приводит к: - проще поддерживать базу данных - проще добавить будущую функциональность - четкое отношение

Единственное, что я хотел бы рассмотреть, если нет почти никакого кода в редакторе просто демпинг поле непосредственно в статье и Модели документов и демпинг Редактор полностью.

+1

Спасибо за очень четкое описание. Да, теперь все имеет смысл. Основная причина для полиморфных отношений заключалась в том, чтобы избежать дублирования кода, и вы правы, article.editor работает только из-за ассоциации. Спасибо, что нашли время ответить –

Смежные вопросы