несколько моделей в Rails с общим интерфейсом - PullRequest
1 голос
/ 19 марта 2010

Я не уверен в лучшей структуре для конкретной ситуации в Rails. У нас есть несколько типов семинаров. Администрация семинаров является одинаковой независимо от типа семинара, поэтому данные для семинаров представлены в единой модели. Мы собираем отзывы участников о семинарах, и анкеты различны для каждого типа семинаров. Я хочу получить обратную связь о мастерской от модели мастерской, но класс связанной модели будет зависеть от типа мастерской. Если бы я делал это не в Rails, я бы создал абстрактный класс для WorkshopFeedback, а затем имел подклассы для каждого типа мастерской: WorkshopFeedbackOne, WorkshopFeedbackTwo, WorkshopFeedbackThree. Я не уверен, как лучше всего справиться с этим с помощью Rails.

В настоящее время у меня есть:

class Workshop < ActiveRecord::Base
  has_many :workshop_feedbacks
end

class Feedback < ActiveRecord::Base
  belongs_to :workshop
  has_many :feedback_ones
  has_many :feedback_twos
  has_many :feedback_threes
end

class FeedbackOne < ActiveRecord::Base
  belongs_to :feedback
end

class FeedbackTwo < ActiveRecord::Base
  belongs_to :feedback
end

class FeedbackThree < ActiveRecord::Base
  belongs_to :feedback
end

Это не самый чистый способ получить доступ к обратной связи от модели мастерской, так как для получения правильной обратной связи потребуется логика, исследующая тип семинара и затем выбрав, например, @ workshop.feedback.feedback_one.

Есть ли лучший способ справиться с этой ситуацией? Было бы лучше использовать полиморфную ассоциацию для обратной связи? Или, может быть, использовать модуль или Mixin для общего интерфейса обратной связи?

Примечание. Я избегаю использования наследования отдельных таблиц, потому что модели FeedbackOne, FeedbackTwo, FeedbackThree не разделяют много общих данных, поэтому я получу большую малонаселенную таблицу с STI.

Ответы [ 2 ]

1 голос
/ 19 марта 2010

Я думаю, что лучшим решением является создание абстрактного класса Workshop и 3 подклассов Workshop1, Workshop2 и Workshop3.

Следовательно, у каждого будет свой набор отзывов: Feedback1 для Workshop1, Feedback2 для Workshop2, ...

Вы можете изменить объявление в подклассах следующим образом:

class Workshop1 < Workshop
  has_many :feedbacks, :class_name => "Feedback1"
end

class Feedback1 < ActiveRecord::Base
  belongs_to :workshop, :class_name => "Workshop1"
end

И в вашем приложении можно использовать workshop.feedbacks и и feedback.workshop независимо от того, к какому классу принадлежит экземпляр Workshop или Feedback.

РЕДАКТИРОВАТЬ: У вас есть три типа семинаров с общей информацией, но каждый семинар имеет определенный вид обратной связи. Поэтому лучше использовать STI для Workshop, а не для Feedback.

0 голосов
/ 19 марта 2010

Вы можете создать подкласс для ваших моделей, например так:

class Workshop < ActiveRecord::Base
  has_many :feedback_ones
  has_many :feedback_twos
  has_many :feedback_threes
  #has_many :feedbacks # This MIGHT work, but is untested.  I'm not at a dev setup to try.
end

class Feedback < ActiveRecord::Base
  belongs_to :workshop
  has_many :feedback_ones
  has_many :feedback_twos
  has_many :feedback_threes
end

class FeedbackOne < Feedback
  belongs_to :feedback
end

class FeedbackTwo < Feedback
  belongs_to :feedback
end

class FeedbackThree < Feedback
  belongs_to :feedback
end

Вероятно, это лучшее решение, и оно чище. Ваша таблица Feedback должна иметь столбец type, который используется для использования одной таблицы для нескольких классов. Это сообщение в блоге дает хорошее базовое введение в понятие Наследование одной таблицы .

...