2011-08-03 104 views
0

我有一個表單,我想同時創建一個父記錄和一個子記錄。舉一個簡單的例子,讓我們說一個公司與第一名員工。Rails的複雜形式

在我的控制器

我做這樣的事情:

def new 
    @company = Company.new 
    @company.employees.new 
end 

,這在我看來:

<%= form_for(@company) do |form| %> 

    <div> 
     <%= form.label :name %> 
     <%= form.text_field :name %> 
    </div> 

    <%= form.fields_for :employees do |employee_form| %> 

     <div> 
      <%= employee_form.label :name %> 
      <%= employee_form.text_field :name %> 
     </div> 

    <% end %> 

<% end %> 

,並回到我的控制器再次:

def create 
    @company = Company.new(params[:company]) 
    @company.employees << Employee.new(params[:company][:employees_attributes]["0"]) 

    # save stuff 
end 

問題1:

我無法獲得公司員工集合中填入的表單中創建的單個員工。當我查看參數時,我發現[:employees_attributes] [「0」]的東西。

我有什麼工作,但有沒有更乾淨的方法來做到這一點?

問題2:

如果驗證未通過的員工,我得到一個通用的「員工是無效的」,而不是需要的名稱驗證消息。我得到我打電話保存在收集和軌道正在盡最大努力冒出一個驗證錯誤,但有沒有一種更清潔的方式來做到這一點,所以我可以得到特定於員工的錯誤?

在短期

如何清潔這件事使相關模型從PARAMS自動創建的,所以我得到的驗證消息的一個員工。

感謝您的期待。

回答

0

1)fields_for安排子對象屬性嵌套在params散列中的父對象屬性中,併發送回控制器動作。要讓Rails自動更新子對象,請使用accep_nested_attributes_for聲明來告訴父模型接受嵌套屬性。

2)每個ActiveRecord對象都有一個錯誤對象。循環顯示錯誤列表並顯示消息。

實現此目的的最佳方法是創建一個部分視圖幫助器方法,它將爲您呈現錯誤。然後用您對render_error_messages方法的調用來替換窗體中生成的錯誤消息。你有所有的代碼已經在生成的表單中執行此操作。您只需將該代碼重構爲部分代碼,創建幫助程序(應該接受一個模型名稱數組作爲參數,然後按照您所需的信息進行操作)。無論是爲每個模型渲染一個部分,還是渲染一個將處理子對象以及父對象的部分。完全是你的電話。

3)更換新的行動來建立,而創造一個新的子對象,而不是

def new 
    @company = Company.new 
    @company.employees.new 
end 

做到這一點

def new 
    @company = Company.new 
    @company.employees.build 
end 

4)看看那些Railscasts怎麼看accepts_nested_attributes工作

http://railscasts.com/episodes/196-nested-model-form-part-1

and

http://railscasts.com/episodes/197-nested-model-form-part-2

更新

那麼,如何在上述信息讓你在關係到你的問題。

1)我有什麼作品,但有沒有更乾淨的方法來做到這一點?

您是否按照上述第3點修正了新操作?現在你的創建動作可以看起來像這樣

def create 
    @company = Company.new(params[:company]) 

    # save stuff 
end 

這更清潔,因爲它已恢復到原始生成的創建操作。 你可能不認爲這是一個更新,因此沒有那麼幹淨。好吧,隔離你會是對的。但考慮到你可以添加儘可能多的關係,只要你喜歡廣告添加儘可能多的fields_for聲明,你可以把用戶 - >員工關係變成has_many(我知道你不會)。你可以做到這一切,你的創建和更新操作保持完全相同,這就是爲什麼它更乾淨。

2)有沒有一種更清潔的方式來做到這一點,以便我可以得到特定於員工的錯誤? 鑑於我在上面第2點中的回答,您知道員工對象以及用戶對象上有錯誤對象嗎?您現在也知道,您可以循環查看錯誤對象以獲取正確的消息嗎? 所以,你可以做到這一點

<% if @user.employee.errors.any? %> 
    <div id="error_explanation"> 
     <h2><%= pluralize(@user.employee.errors.count, "error") %> prohibited this user from being saved:</h2> 

     <ul> 
     <% @user.employee.errors.full_messages.each do |msg| %> 
     <li><%= msg %></li> 
     <% end %> 
     </ul> 
    </div> 
    <% end %> 

在重複自己的風險,我只想說,你應該重構你的錯誤信息查看代碼放到一個部分,將採取任何對象作爲參數,那麼你可以把它叫做任何視圖,從而使您可以更改所有表單的樣式和功能。

希望更清楚

+0

感謝您的迴應。我已經在父模型中設置了accep_nested_attributes_。我已經有了一個部分,它的作用是model.errors.full_messages.each,我得到的是「Employees is invalid」,而不是「Name不能爲空」。在閱讀兩者之間的細微差別後,關於構建的建議很有意義,謝謝。在尋求幫助之前,我已經觀看了Railscasts。不知道我留下的是什麼,其他任何想法都會很棒,但不知道我能從我的結局中得到什麼。再次感謝。 – blu

+0

我的確涵蓋了這些要點,但也許我所說的不夠清楚。我會更新我的答案,使其更清晰 – jamesc

+0

@blu - 我已更新我的答案,希望您現在可以看到如何使用我給你的信息 – jamesc