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」中工作?謝謝! –