值得注意的是,这个问题主要是一个理论上的问题。我怀疑真正的答案是“小心不要这样做!” 继续前进。也就是说,如果有办法做到这一点,那就太棒了,这样如果发生这种特殊的错误——不可避免地会发生——我们可以得到关于何时、如何、谁、为什么的明确答案。我正在努力发展我对软件工程的专业理解,所以如果答案是“有缺陷的数据结构”或类似的东西,请说出来。
我正在使用继承在不同对象之间共享数据。最值得注意的是,整个对象链只是单个父对象的子类。因此,围绕这些对象的邮件实际上是相同的。结果文本有一些细微差别,但设置代码可以相同。
问题是,虽然使用数据对象的超类有时可能是有效的(细节不同,但很多核心逻辑是相同的,因此这里的继承模式),它永远不可能,也绝不能有效使用根邮件对象。我已经设置好了,所以我从不创建根数据对象;这样做在技术上是无效的,但我认为我不能在不禁止使用该根模型的情况下禁止这样做,这违背了继承的目的。
一些示例代码来澄清我的问题:
class RentalEndingWorker
# stripped to psuedocode
def perform
rentals = Rental.rental_expiring_soon.where(warned:false)
rental.deliver_warning_email
end
end
class RentalMailer < ApplicationMailer
def expiring_rental(rental)
@rental = rental
@client = rental.client
@download = rental.show_download
mail(to: @client.email, subject: 'Rental Expiring')
end
end
class DigitalRentalMailer < RentalMailer
def expiring_rental(rental)
@download = rental.digital_download
super
end
end
class EquipmentRentalMailer < RentalMailer
def expiring_rental(rental)
@equipment = rental.equipment_variant
super
end
end
设备租赁和数字租赁的租赁结构完全不同。在相关视图中,我将要使用完全不同的关系链来描述它们。数字下载的“名称”与其父级、DigitalProduct、DigitalVariant 及其相关分类相关。设备的“名称”建立在它与 Equipment & EquipmentVariant 及其相关分类对象的关系之上。
真正好的——据我所知绝对不可能——将是:
class RentalMailer < ApplicationMailer
def expiring_rental(rental)
if called_directly_and_not_by_super
Rollbar.error("Rental Mailer Used Directly")
end
@rental = rental
@client = rental.client
@download = rental.show_download
mail(to: @client.email, subject: 'Rental Expiring')
end
end