Я думаю, у вас есть два основных варианта:
(1) Создайте два типа / модели транзакций: product_transactions и service_transactions.Оба могут наследовать от общего модуля транзакций.Этот подход позволяет вам игнорировать вопрос о том, с какой транзакцией я имею дело?и сосредоточиться на общих деталях реализации в модуле транзакций.Затем вы можете поддерживать два более простых вложенных контроллера, /products/<id>/transactions
и /services/<id>/transactions
, которые не требуют проверки типов.
(2) Переместите проверку типов в общую модель транзакций.Этот подход предполагает, что взаимодействия между транзакцией и продуктом или услугой будут обрабатываться через модуль транзакции, поэтому вы не будете знать, с какой из них вы взаимодействуете.Например:
class Transaction
belongs_to :service
belongs_to :product
def parent
@parent ||= product || service
end
def call_some_action_on_parent
parent.some_action
end
end
Вы можете сделать что-то похожее в вашем контроллере:
@parent = params[:service_id].blank? ? Product.find(params[:product_id]) : Service.find(params[:service_id])
@transaction = @parent.transactions.build(params[:transaction])
Опция, которую вы выбираете, должна действительно быть решением, основанным на ваших потребностях, связанных с объектом транзакции.Если пользовательского кода много, в зависимости от того, взаимодействуете ли вы с продуктом или услугой, вы должны следовать первому подходу.Если код, по сути, одинаков, вам следует воспользоваться вторым подходом и сосредоточиться на контракте между транзакцией и ее родительским объектом (продуктом, услугой или другим) и игнорировать тип объекта.По сути, вас действительно интересует только то, реагирует ли родительский объект на конкретные методы, а не то, какой это на самом деле объект.Как правило, по возможности избегайте проверки типов и сосредоточьтесь на responseds_to?метод вместо.