4

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

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

  • 导轨 3.2
  • 蒙古族
  • 简单的模式

这是我到目前为止的一个简化示例:

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()

这个例子中会出现的问题是它不能渲染,truck_field因为Car没有truck_field方法。除了抛出任何表单助手并手动管理 html 和字段值之外,我不确定如何解决这个问题。即使经过大量谷歌搜索,我也无法找到这种形式的任何示例。

如何使用现有的表单助手以标准的“Rails 方式”解决这个问题?

4

2 回答 2

2

我想我也有类似的问题,但是has_one我有has_many.

基本上我使用cocoongem 为每个装饰类(例如Caror Truck)动态添加字段,然后我accept_nested_attributes_for :vehicle. 表单是动态构建的,在提交时,参数进入内部vehicle_attributes

代码看起来像(为has_one关联而更新):

# _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_fieldspartial 您检查它是什么对象(CarTruck)并呈现正确的字段。

我认为这很好用,而且正是我所需要的。希望能帮助到你。

我写了一个更长的解释:http ://www.powpark.com/blog/programming/2014/05/07/rails_nested_forms_for_single_table_inheritance_associations

于 2014-05-07T21:18:40.717 回答
1

这是直接将表单映射到模型并不理想的情况之一。我认为用户填充的表单映射和持久性模型实例是两个非常不同的概念。

您可以尝试将 Vehicle 子类化为用于接受表单数据的类。然后混合处理表单特定内容所需的所有额外代码。这样,您可以保持Vehicle模型清洁。您还可以重写方法VehicleFormModel以像工厂一样工作,以便在创建对象时构建正确的实例。在您的控制器中,实例化 VehicleFormModel 而不是 Vehicle。

class VehicleFormModel < Vehicle
  include Car::FormModel
  include Truck::FormModel

  def self.build
    # Use a form field to handle specifics for each type,
    # delegating to the mixed in FormModel as needed
  end

end

class Car < Vehicle
  module FormModel
    def self.included(base)
      base.class_eval do
        field :car_field
        attr_accessible :car_field
      end
    end
  end
end
于 2013-07-04T16:09:14.237 回答