嵌套表单:资源动态添加但是没有创建?

时间:2011-07-23 14:07:22

标签: ruby-on-rails ruby ruby-on-rails-3 nested-forms

我正在使用nested form gem,我会动态地向表单添加产品。当我点击“添加”时,会出现另一个产品资源,但在创建时它会删除前者完全创建的资源。这是场景的方式:

  1. 填写位置
  2. 选择日期
  3. 填写产品(一个已经在表格中)
  4. 再添加5个产品(产品2,3,4,5)
  5. 填写所有产品
  6. “点击”创建
  7. 创建产品5

  8. 这是我的嵌套表单的外观:

    <%= nested_form_for @location, :url => products_path(@product) do |f| %>
        <%= f.label :business %>
        <%= f.text_field :business %>
        <%= f.label :address %>
        <%= f.text_field :address %>
    
     <%= f.fields_for :product_dates, :url => products_path(@product) do |d| %>
         <%= d.label :date %>
         <%= d.date_select :date %>
    
     <%= d.fields_for :products, :url => products_path(@product) do |p| %>
         <%= p.text_field :name %>
         <%= p.text_field :price %>
         <%= p.text_field :tag_list %>
         <%= p.link_to_remove "Remove Product" %>       
         <% end %>
         <%= d.link_to_add "Add", :products %>
     <% end %>
     <%= f.submit "Finish" %>
    <% end %>
    

    控制器:

    class ProductsController < ApplicationController
    
        def new
            @location = Location.new
            @product = Product.new
            product_date = @location.product_dates.build
            product_date.products.build
        end
    
        def create
            @location = Location.create(params[:location])
            if @location.save
                flash[:notice] = "Products Created."
                redirect_to :action => 'index' 
            else
                render :action => 'new'
            end
      end
    

    模型:

    class User < ActiveRecord::Base
      devise
      attr_accessible :email, :password, :password_confirmation, :remember_me
      has_many :products,  :dependent => :destroy
    end
    
    
    class Location < ActiveRecord::Base
        attr_accessible :address, :business, :product_dates_attributes
        has_many :products
        has_many :product_dates 
        accepts_nested_attributes_for :product_dates    
    end
    
    class ProductDate < ActiveRecord::Base
        attr_accessible :date, :products_attributes
        belongs_to :location
        belongs_to :user
        has_many :products
        accepts_nested_attributes_for :products
    end
    
    class Product < ActiveRecord::Base
        attr_accessible :name, :price, :tag_list
        belongs_to :user
        belongs_to :location
        belongs_to :product_date
    end
    

    任何建议?

1 个答案:

答案 0 :(得分:1)

首先删除fields_for声明中的url_for声明,以便获得

<%= nested_form_for @location, :url => products_path(@product) do |f| %>
    <%= f.label :business %>
    <%= f.text_field :business %>
    <%= f.label :address %>
    <%= f.text_field :address %>

    <%= f.fields_for :product_dates do |d| %>
       <%= d.label :date %>
       <%= d.date_select :date %>

       <%= d.fields_for :products do |p| %>
         <%= p.text_field :name %>
         <%= p.text_field :price %>
         <%= p.text_field :tag_list %>
         <%= p.link_to_remove "Remove Product" %>       
       <% end %>
       <%= d.link_to_add "Add", :products %>
    <% end %>
 <%= f.submit "Finish" %>
<% end %>

真正令人困惑的是你的整个路由和params方法。这是不对的。你有一个form_for @location,其中包含:url products_path(@product)这样做会对皇家造成问题所带回的params的问题。 通过从您的nested_form_for声明中删除products_path(@product)来坚持路由到位置控制器而不是产品控制器,您会发现您将保存所有必要的记录,但您很可能需要更改locations_controller创建中的redirect_to声明行动和update_action相同。

但是,当您处理某个位置时,为什么要使用产品控制器呢?再次,这不是自然或直观的。

最后一件事。您的删除链接无法正常工作,因为您尚未添加必要的内容:dependent =&gt; :破坏has_many声明的声明,你也错过了:reject_if procs和:allow_destroy =&gt; accept_nested_attributes声明的真实声明。

我可以强烈建议你 1)使用位置控制器或产品控制器,而不是两者 我的意思是链接到这个表单link_to locations controller并设置所有内容或使用form_for @product而不是@location并处理产品控制器中的所有内容

2)观看此宝石所基于的轨道广播 http://railscasts.com/episodes/196-nested-model-form-part-1 http://railscasts.com/episodes/197-nested-model-form-part-2

3)花一些时间了解rails表单视图助手如何安排在控制器操作中组织params哈希。在您的情况下,请仔细查看您的日志文件,了解当前所针对的参数。 您很可能会看到params没有嵌套,因为您将它们排除,这就是嵌套属性声明不按预期运行的原因