在 Rails 上的 Ruby 中实施 STI,如何将对象从一个 class 复制到另一个?
Implementing STI in Ruby on Rails, how can I duplicate an object from one class to the other?
我实现了 STI 来分离两种类型的技能对象:DefinedSkill 和 DeployedSkill。他们在物理上非常接近,但管理方式不同。
DefinedSkill 的一个方法是 deploy 方法,它创建了几乎相同的 DeployedSkill。
最初,我是这样写的:
def deploy
@template_skill = DefinedSkill.find(params[:id])
if @template_skill.status.code == "ACCEPTED"
@deployed_skill = @template_skill.deep_clone include: [:translations]
@deployed_skill.type = 'DeployedSkill'
---
@deployed_skill.save
end
end
但这会生成 DefinedSkill class 的对象,即使我尝试分配 type 属性。
然后我尝试在属性级别工作,并写了这个:
def deploy
@template_skill = DefinedSkill.find(params[:id])
if @template_skill.status.code == "ACCEPTED"
@deployed_skill = DeployedSkill.new(@template_skill.attributes.except(:id, :type))
# @deployed_skill.type = 'DeployedSkill' (useless as type is managed by STI feature)
---
@deployed_skill.save
end
end
但这会产生以下错误:
ActiveRecord::SubclassNotFound (Invalid single-table inheritance type: DefinedSkill is not a subclass of DeployedSkill)
所以这是我的问题:如何在 STI 的上下文中创建同级对象 class?
而不是设置 @deployed_skill = type
,尝试使用 becomes
方法:
@deployed_skill.becomes(DeployedSkill)
非常感谢 msencenb 和 felipeecst 让我上路。
看了文档试了一下,得出的结论是现有对象无法转换,但是class创建新实例时应该进行转换。
我应用的方案是:
@deployed_skill = @template_skill.becomes!(DeployedSkill).deep_clone include: [:translations]
解决了我的问题。
我实现了 STI 来分离两种类型的技能对象:DefinedSkill 和 DeployedSkill。他们在物理上非常接近,但管理方式不同。
DefinedSkill 的一个方法是 deploy 方法,它创建了几乎相同的 DeployedSkill。
最初,我是这样写的:
def deploy
@template_skill = DefinedSkill.find(params[:id])
if @template_skill.status.code == "ACCEPTED"
@deployed_skill = @template_skill.deep_clone include: [:translations]
@deployed_skill.type = 'DeployedSkill'
---
@deployed_skill.save
end
end
但这会生成 DefinedSkill class 的对象,即使我尝试分配 type 属性。
然后我尝试在属性级别工作,并写了这个:
def deploy
@template_skill = DefinedSkill.find(params[:id])
if @template_skill.status.code == "ACCEPTED"
@deployed_skill = DeployedSkill.new(@template_skill.attributes.except(:id, :type))
# @deployed_skill.type = 'DeployedSkill' (useless as type is managed by STI feature)
---
@deployed_skill.save
end
end
但这会产生以下错误:
ActiveRecord::SubclassNotFound (Invalid single-table inheritance type: DefinedSkill is not a subclass of DeployedSkill)
所以这是我的问题:如何在 STI 的上下文中创建同级对象 class?
而不是设置 @deployed_skill = type
,尝试使用 becomes
方法:
@deployed_skill.becomes(DeployedSkill)
非常感谢 msencenb 和 felipeecst 让我上路。 看了文档试了一下,得出的结论是现有对象无法转换,但是class创建新实例时应该进行转换。
我应用的方案是:
@deployed_skill = @template_skill.becomes!(DeployedSkill).deep_clone include: [:translations]
解决了我的问题。