0

我在听Hypercritical时听说过这个社区,我很高兴能够加入我的第一个问题。我正在开发我的第一个Rails应用程序,并且遇到了一个我似乎无法解决的问题。我一直在观看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

我想通了。事实证明,除了@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)))' 

所以我在我的路由更新为新的REST风格的路线风格:

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 
+0

我用更多的解释更新了我的答案。你应该阅读,这是肯定更清楚:http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for – Damien

0

你只是忘了分配@busines s_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 } 

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

我希望它有帮助。

+0

Hi @Delba。感谢您的答复。我提出了你所建议的改变,并且它有一次工作,但Business Developer的价值为NULL。奇怪的是,现在它甚至没有创建一个商业开发人员,并且与以前一样。控制台显示“警告:无法批量分配受保护的属性:business_developer”。我认为这与attr_accessible有关,但我不确定是什么。你有什么想法? –

+0

我的不好。我没有看太深的代码。编写accep_nested_attributes_for:business_developers(而不是:business_developer_service_offerings)。让我保持联系 – Damien

+0

我解释我在下面的答案中找到的解决方案。但是,您能否解释在视图中如何使用“@business_developer = @ service_offering.business_developers.build”中的“@business_developer”?与“fields_for”中的“:business_developer”是否一样?如果是这样,为什么“@business_developer”不能在视图中而不是在“:business_developer”中工作?谢谢! –