嵌套模型表单不提交所有内容

时间:2011-11-22 18:12:01

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

我在听Hypercritical时听说过这个社区,我很高兴能加入我的第一个问题。我正在开发我的第一个应用程序,我遇到了一个我似乎无法破解的问题。我一直在看Railscast,Lynda.com和谷歌搜索几天,但我仍然无法理解如何创建一个会更新我的has_many的表单:通过关联立刻。请允许我尝试解释一下我在做什么。

我的目标: 我工作的公司提供了许多“服务产品”,我希望能够在一个页面上创建一个新的服务产品,并让它创建联系人和与之相关的其他信息。诸如“联系人”之类的附加信息将存在于他们自己的表中,因为它们可能需要被许多“服务产品”引用。

问题: 当我提交表单时,“服务产品”字段提交并输入到数据库中,但“业务开发人员”的字段不会。显然,我希望将所有内容输入到相应的表中,并将要在连接表中链接的ID。我非常感谢您提供的任何见解。

我到目前为止:您在下面看到的是服务产品和业务开发人员。最终我将添加联系人,照片和文件,但我想我会简单地开始工作。

型号:

class ServiceOffering < ActiveRecord::Base
 attr_accessible :name, :description
 has_many :business_developer_service_offerings
 has_many :business_developers, :through => :business_developer_service_offerings
 accepts_nested_attributes_for :business_developer_service_offerings
end

class BusinessDeveloper < ActiveRecord::Base
 attr_accessible :first_name, :last_name
 has_many :business_developer_service_offerings
 has_many :service_offerings, :through => :business_developer_service_offerings
end

class BusinessDeveloperServiceOffering < ActiveRecord::Base
 belongs_to :business_developer
 belongs_to :service_offering
end

控制器:

def new
 @service_offering = ServiceOffering.new
 @service_offering.business_developers.build
end

def create
 @service_offering = ServiceOffering.new(params[:service_offering])
 if @service_offering.save
  redirect_to(:action => 'list')
 else
  render('new')
 end
end

查看:

<%= form_for((@service_offering), :url => {:action => 'create'}) do |f|%>
    <p>
    <%= f.label :name%>             
    <%= f.text_field :name %>

    <%= f.label :description%>  
    <%= f.text_field :description %>
    </p>

<%= f.fields_for :business_developer do |builder| %>
    <p>
    <%= builder.label :first_name%>
    <%= builder.text_field :first_name %>

    <%= builder.label :last_name%>
    <%= builder.text_field :last_name %>
    </p>
<%end%>
    <%= f.submit "Submit" %>
<%end%>

2 个答案:

答案 0 :(得分:2)

我明白了。事实证明,除了@Delba提出的两个建议之外,还有一些问题需要改变。

表格:

我再次看了RailsCasts #196并注意到我的表单看起来与那里使用的表单不​​同,所以我尝试将其匹配:

    <%= form_for @service_offering do |f|%>
     <p>
      <%= f.label :name%>             
      <%= f.text_field :name %>

      <%= f.label :description %>  
      <%= f.text_field :description %>
     </p>
    <%= f.fields_for :business_developers do |builder| %>
     <p>
      <%= builder.label :first_name %>
      <%= builder.text_field :first_name %>

      <%= builder.label :last_name %>
      <%= builder.text_field :last_name %>
     </p>
<%end%>
    <%= f.submit "Submit" %>
<%end%>

最初,这出现了错误:

undefined method `service_offerings_path'

<强>路线:

这让我了解RESTful Routes,因为我使用的是旧的路由样式:

match ':controller(/:action(/:id(.:format)))'

所以我将路由更新为新的RESTful Routes样式:

  get "service_offerings/list"
  resource :service_offerings
  resource :business_developers

<强> attr_accessible

表单可见,但仍无法正常工作。所以我在这个网站上做了一些搜索,发现this post谈到了在attr_accessible下为你的父对象模型添加“something_attributes”。所以我做了:

class ServiceOffering < ActiveRecord::Base 
 has_many :business_developer_service_offerings
 has_many :business_developers, :through => :business_developer_service_offerings
 accepts_nested_attributes_for :business_developers
 attr_accessible :name, :description, :business_developers_attributes  
end

随着@ Delba在上面列出的模型和控制器中显示的建议的改变解决了这个问题。

def new
 @service_offering = ServiceOffering.new
 @business_developer = @service_offering.business_developers.build
end 

答案 1 :(得分:0)

你忘了分配@business_developper。

def new
  @service_offering = ServiceOffering.new
  @business_developper = @service_offering.business_developpers.build
end

-

@business_developer = @service_offering.business_developers.build

初始化biz_dev的一个实例,然后在视图中可用。 fields_for:biz_dev并不是真的与这个实例绑定,而是与多对多关系btw serv_off和biz_dev绑定。

通过这种方式,如果在控制器中初始化另一个biz_dev实例,则可以为其他biz_dev添加多个输入。例如:

5.times { @service_offering.biz_dev.build }

将在您的表单中添加其他字段,而无需在视图中声明它们。

我希望它有所帮助。