多态/单表继承关联的Rails嵌套属性形式 [英] Rails nested attributes form for polymorphic/single table inheritance associations

查看:108
本文介绍了多态/单表继承关联的Rails嵌套属性形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一种表单(使用SimpleForm),该表单允许您编辑嵌入式关联.我遇到的问题是嵌套模型是子类,因此它们是具有可能不同字段的不同类型.我正在为每种类型的模型创建隐藏的表单,并使用JavaScript显示所选类型的表单.

I am working on a form (using SimpleForm) that allows you to edit embedded associations. The problem that I'm running into is that the nested models are subclasses so they are different types with potentially different fields. I'm creating hidden forms for each type of model, and using JavaScript to display the form for the selected type.

仅供参考,我正在使用以下宝石:

FYI, I'm using the following gems:

  • Rails 3.2
  • Mongoid
  • SimpleForm

这是到目前为止我所拥有的简化示例:

Here's a simplified example of what I have so far:

class Garage
  include Mongoid::Document
  embeds_one :vehicle
  accepts_nested_attributes_for :vehicle
end

class Vehicle
  include Mongoid::Document
  embedded_in :garage
  attr_accessible :_type
end

class Car < Vehicle
  field :car_field
  attr_accessible :car_field
end

class Truck < Vehicle
  field :truck_field
  attr_accessible :truck_field
end

在控制台中:

> garage = Garage.new
> garage.vehicle = Car.new(car_field: 'something')
> garage.save!

采用以下形式:

= simple_form_for @garage do |f|
  = f.input :vehicle do |vehicle_form|
     = vehicle_form.input :_type, collection: ['Car', 'Truck']

  %span.hide{data:{fields-for:'Car'}}
    = vehicle_form.input :car_field

  %span.hide{data:{fields-for:'Truck'}}
    = vehicle_form.input :truck_field

:coffeescript
  $('#garage_vehicle_attributes__type').change ->
    type = $(@).find('option:selected').val()
    $('[data-fields-for="' + type + '"]').show()

在此示例中将发生的问题是,由于Car没有truck_field方法,因此它将无法呈现truck_field.除了扔掉任何表单助手和手动管理html和field值之外,我不确定如何解决此问题.即使经过大量的Google搜索,我也找不到任何这种形式的示例.

The problem that will occur in this example is that it won't be able to render the truck_field because Car does not have a truck_field method. I'm not sure how to solve this problem besides throwing out any form helpers and managing the html and field values manually. Even after much Googling, I haven't been able to find any examples of this type of form.

如何使用现有的表单助手以标准的轨道方式"解决此问题?

How can this problem be solved in a standard, "Rails way" using existing form helpers?

推荐答案

我认为我也有类似的问题,但是除了has_one关系之外,我还有has_many.

I think I had a similar problem, however instead of a has_one relationship, I have has_many.

基本上,我使用cocoon gem为每个经过修饰的类(例如CarTruck)动态添加字段,然后使用accept_nested_attributes_for :vehicle.表单是动态构建的,并且在提交时,参数位于vehicle_attributes内部.

Basically I used cocoon gem to dynamically add fields for each decorated class (such as Car or Truck) and then I accept_nested_attributes_for :vehicle. The form is built dynamically and on submit, the parameters go inside vehicle_attributes.

代码类似于(针对has_one关联进行了更新):

The code looks something like (updated for has_one association):

# _form.html.haml

= simple_form_for @garage, :html => { :multipart => true } do |f|

  = f.simple_fields_for :vehicles do |vehicle|
    = render 'vehicle_fields', :f => item
    = 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部分中检查它是什么对象(CarTruck),然后呈现正确的字段.

Then inside _vehicle_fields partial you check what object it is (Car or Truck) and you render the correct fields.

我认为这很好用,这正是我所需要的.希望对您有所帮助.

I think this works quite good, and was exactly what I needed. Hope it helps.

我在以下位置写了更长的说明: http://www.powpark .com/blog/programming/2014/05/07/rails_nested_forms_for_single_table_inheritance_associations

I wrote a longer explanation at: http://www.powpark.com/blog/programming/2014/05/07/rails_nested_forms_for_single_table_inheritance_associations

这篇关于多态/单表继承关联的Rails嵌套属性形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆