2010-03-19 3 views
1

Я не уверен в лучшей структуре для конкретной ситуации в Rails. У нас есть несколько типов мастерских. Администрация семинаров одинакова независимо от типа рабочего места, поэтому данные для мастерских находятся в одной модели. Мы собираем отзывы участников о семинарах, и вопросник различается для каждого типа семинара. Я хочу получить обратную связь о семинаре с моделью семинара, но класс соответствующей модели будет зависеть от типа семинара. Если бы я делал это в чем-то отличном от Rails, я бы создал абстрактный класс для WorkshopFeedback, а затем имел подклассы для каждого типа семинара: WorkshopFeedbackOne, WorkshopFeedbackTwo, WorkshopFeedbackThree. Я не уверен, как лучше всего справиться с Rails.несколько моделей в 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, а затем выбрать, например, @ workshop.feedback.feedback_one.

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

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

ответ

1

Я думаю, что лучшим решением будет создание абстрактного класса 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.

EDIT: У вас есть три типа мастерских с общей информацией, но каждая мастерская имеет определенный вид обратной связи. Поэтому лучше использовать STI для Workshop, а не для обратной связи.

0

Вы можете унаследовать свои модели, например, так:

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, который используется для использования одной таблицы для нескольких классов. This blog post дает хорошее базовое введение в концепцию Single Table Inheritance.

+1

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