更新:在考虑了这个之后,我认为这个问题包括多态性和STI。
假设我有以下内容:
class Vehicle < ActiveRecord::Base
belongs_to :dealership
...
end
class Car < Vehicle
...
end
class Truck < Vehicle
...
end
Car and Truck车型具有相同的属性,但模型中的逻辑不同,因此它们都只使用车辆表。
我想制作一个通用表格,允许某人创建新的车辆记录,并选择它是“汽车”还是“卡车”。在后端,此表格应创建“汽车”或“卡车”记录,而不是通用的“车辆”记录。
问题: 你如何在Rails表单中提供此选项?具体来说,是否存在列出抽象基本模型的子类型的方法,和/或是否有一种简单的方法将它们表示为(例如)表单中的Select元素?
我希望创建一个可以制造汽车或卡车的形式,而不是只有两种不同形式的汽车和卡车,最终我也希望这些模型嵌套在父母身上,“经销商“。我希望不仅能够创建新车并选择“汽车”或“卡车”作为选项,而且能够拥有嵌套表格,用户可以加载“经销商”并查看/编辑所有车辆和卡车属于该经销商的单一形式。我知道如何在accepts_nested_attributes_for
之类的简单关联上使用Vehicle belongs_to :dealership
进行设置,但我不确定如何为从Vehicle继承的子模型设置它。
答案 0 :(得分:1)
我遇到了同样的问题。基本上,您正在尝试构建一个接受基类has_many
关联的表单,但您希望动态地为任何装饰/具体类创建单独的表单(添加嵌套字段)。
我使用cocoon
gem解决了这个问题,它提供了向表单动态添加正确字段的方法。 _form
部分看起来像:
# _form.html.haml
= simple_form_for @dealership, :html => { :multipart => true } do |f|
= f.simple_fields_for :vehicles do |vehicle|
= render 'vehicle_fields', :f => vehicle
= link_to_add_association 'Add a Car', f, :vehicles, :wrap_object => Proc.new { |vehicle| vehicle = Car.new }
= link_to_add_association 'Add a Truck', f, :vehicles, :wrap_object => Proc.new { |vehicle| vehicle = Truck.new }
= f.button :submit, :disable_with => 'Please wait ...', :class => "btn btn-primary", :value => 'Save'
然后是_vehicle_fields
# _vehicle_fields.html.haml
- if f.object.type == 'Car'
= render 'car_fields', :f => f
- elsif f.object.type == 'Truck'
= render 'truck_fields', :f => f
car_fields
和truck_fields
还会包含link_to_remove_association
提供的链接cocoon
查看https://github.com/nathanvda/cocoon上的:wrap_object
文档,或阅读http://www.powpark.com/blog/programming/2014/05/07/rails_nested_forms_for_single_table_inheritance_associations上的博客文章
答案 1 :(得分:0)
我可能错了,但我理解polymorphic
是另一种方式。我的意思是,模型可以属于多个其他模型...
Car
和Truck
是一种Vehicle
。因此,我们可以说Vehicle
具有year
和mark
属性。
您可以创建新的Car
或Truck
,并且定义了多态,您将照常创建表单。
@car = Car.find(id)
@vehicle = @car.vehicles.build(year: "1999", mark: "Beetle")
@vehicle.save
我希望它有所帮助...
答案 2 :(得分:0)
我不认为表单上的简单选择元素是您问题的解决方案。您在此处尝试实现的目标称为Multiple Table Inheritance
,您的问题应该是您必须构建模型以便轻松反映在数据库中的方式。因为这是一个长时间的讨论,我将指向this article,在那里我解释了这样做的最佳方式。我希望我能以某种方式帮助你:)
PS:回答你的问题,在Rails框架中没有没有内置的机制来做这种事情。