首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于多态/单表继承关联的Rails嵌套属性形式

用于多态/单表继承关联的Rails嵌套属性形式
EN

Stack Overflow用户
提问于 2013-07-01 19:43:07
回答 2查看 2.3K关注 0票数 4

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

FYI,我使用以下宝石:

  • Rails 3.2
  • 蒙古人
  • SimpleForm

下面是我到目前为止所得到的一个简化的例子:

代码语言:javascript
复制
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

在控制台中:

代码语言:javascript
复制
> garage = Garage.new
> garage.vehicle = Car.new(car_field: 'something')
> garage.save!

形式如下:

代码语言:javascript
复制
= 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和字段值之外。即使在谷歌上搜索了很多之后,我也没能找到任何这种形式的例子。

如何使用现有的表单帮助程序来解决这个问题呢?

EN

回答 2

Stack Overflow用户

发布于 2014-05-07 21:18:40

我想我也有一个类似的问题,但是我没有has_one关系,我有has_many

基本上,我使用cocoon gem为每个修饰类(如CarTruck)动态添加字段,然后为i accept_nested_attributes_for :vehicle添加字段。表单是动态构建的,在提交时,参数在vehicle_attributes中。

代码看起来类似于(更新为has_one关联):

代码语言:javascript
复制
# _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),并呈现正确的字段。

我认为这很好,也正是我所需要的。希望能帮上忙。

我写了一个更长的解释:associations

票数 2
EN

Stack Overflow用户

发布于 2013-07-04 16:09:14

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

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

代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17412409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档