假设我的数据库中有一个FireNinja < Ninja
对象,使用单表继承存储。后来,我意识到他真的是WaterNinja < Ninja
。将他改为不同的子类最干净的方法是什么?更好的是,我想创建一个新的WaterNinja
对象,只需替换数据库中的旧FireNinja
,保留ID。
修改
我知道如何从现有的WaterNinja
创建新的FireNinja
对象,我也知道我可以删除旧的{{1}}并保存新的对象。我想做的是 mutate 现有项目的类。我是通过创建一个新对象并做一些ActiveRecord魔术来替换行,或者通过对对象本身做一些疯狂的事情,或者甚至通过删除它并重新插入相同的ID来做到这一点是问题的一部分。
答案 0 :(得分:8)
您可以通过
让FireNinja充当WaterNinja@ninja.becomes(WaterNinja)
如果要永久更改类,则只需覆盖type属性。
@ninja.type = "WaterNinja"
@ninja.save!
答案 1 :(得分:2)
你需要做两件事:
WaterNinja < Ninja
ninjas
表中运行类似UPDATE ninjas SET (type = 'WaterNinja') WHERE (type = 'FireNinja')
就是这样。
对于进行运行时转换,这样做,但我不建议。
class Ninja
def become_another_ninja(new_ninja_type)
update_attribute(:type, new_ninja_type)
self.class.find(id)
end
end
@water_ninja = @fire_ninja.become_another_ninja('WaterNinja')
问题在于@fire_ninja现在将成为一次性对象。
答案 2 :(得分:0)
支持组合而不是继承 - 您应该使用策略模式在运行时更改此类行为。
答案 3 :(得分:-1)
您必须定义WaterNinja#to_fireninja
方法。 Ruby无法更改对象的类,同时保持对象的相同对象。
class WaterNinja < Ninja
def to_fireninja
FireNinja.new :name => name
end
end