我在听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%>
答案 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 }
将在您的表单中添加其他字段,而无需在视图中声明它们。
我希望它有所帮助。