Ruby on rails Rails更改对象的多态类型
我们有一个父模型车辆,继承来制造汽车、卡车、SUV。在我们的表单中,我们允许用户编辑一组车辆的数据,每个车辆的属性之一是“类型”的选择菜单。HTML属性名为vehicle_type,并更新车辆模型中的实际多态类型属性:Ruby on rails Rails更改对象的多态类型,ruby-on-rails,inheritance,polymorphism,Ruby On Rails,Inheritance,Polymorphism,我们有一个父模型车辆,继承来制造汽车、卡车、SUV。在我们的表单中,我们允许用户编辑一组车辆的数据,每个车辆的属性之一是“类型”的选择菜单。HTML属性名为vehicle_type,并更新车辆模型中的实际多态类型属性: # Get/Set Type bc rails doesnt allow :type to be set in mass def vehicle_type self.type end def vehicle_type=(type) self.typ
# Get/Set Type bc rails doesnt allow :type to be set in mass
def vehicle_type
self.type
end
def vehicle_type=(type)
self.type = type
end
我们遇到的问题是,当我们对表单数据调用update_属性并且现有车辆的类型已经更改时,rails正在调用旧类(而不是新类型)的验证,这会导致错误。我们需要做的是,当车辆类型改变时,模型也改变为新类型
有办法做到这一点吗
以下是更新操作(车队有许多车辆): 这里是舰队:
class Fleet < ActiveRecord::Base
has_many :vehicles, :dependent => :destroy, :order => 'position ASC'
accepts_nested_attributes_for :vehicles,
:reject_if => proc { |attrs| attrs['name'].blank? },
:allow_destroy => true
class Fleet:destroy,:order=>'position ASC'
接受车辆的\u嵌套\u属性\u,
:reject_if=>proc{| attrs | attrs['name'].blank?},
:allow_destroy=>true
当您调用@vehicle.save
时,您可以添加false
作为跳过验证的第一个参数(@vehicle.save(false)
)。另一个选项是使用ActiveRecord::Base#update_属性
——它跳过验证
因此,您可以在不更改“类型”列的情况下保存模型,然后在同一操作中添加
@vehicle.update_属性(:type,“Truck”)
。两个SQL查询,但对于您的情况可能是必需的。您可以使用工厂方法创建正确的车辆类型,然后分配属性
def Vehicle.factory(type)
type.constantize.new
end
模型是否使用单表继承?你能为有问题的控制器发布更新操作吗?嘿,EmFi,是的,他们使用单表继承。上面的问题用更新代码进行了更新。这需要同时抛弃update_attributes方法并手动迭代每辆车,对吗?我希望可以有一种很好的方法来保留update\u属性代码(我在问题中添加了控制器代码)。是的,我对accepts\u nested\u attributes\u for做的不多,所以我不知道如何修改它创建的方法。(我仍然对嵌套表单使用旧的“ryanb”方法。)这是Rails中的一个非常新的功能,我在lighthouse中没有看到一张罚单。我会看看我是否可以在本地复制它,然后添加一张罚单。如果我这样做,尽管我们不再得到车辆的任何验证,对吗?我希望有一种方法可以保持对车辆(恰好是正确的车辆)的验证,而不必手动迭代每个车辆来执行此操作(即仍然使用update_属性)。
def Vehicle.factory(type)
type.constantize.new
end