2009-05-03 44 views
2

我有一個叫做Contact的模型,has_one是這樣的。如何讓form.select在Rails中返回一個模型?

class Contact < ActiveRecord::Base 
    has_one :guest, :class_name => "Contact", :foreign_key => "guest" 
end 

在我創建視圖我使用的是選擇輔助方法,列出了可能被選擇作爲像這樣客人的所有聯繫人...

<% form_for(@contact) do |f| %> 
    <%= f.error_messages %> 
    ... 
    <p> 
     <%= f.label :guest %><br /> 
     <% @guests = Contact.find(:all, :order => "lastname").map { |u| [u.lastname + ', ' + u.firstname, u.id] } %> 
     <%= f.select :guest, @guests, {:include_blank => true} %> 
    </p> 
    ... 
<% end %> 

每當這個表單提交,我得到一個錯誤表示它期待一個聯繫人,但得到一個字符串。

在將當前聯繫人保存到數據庫之前,我應該在何處以及如何將表單提交的字符串轉換爲聯繫人?

回答

6

當您在Rails中創建關聯(如has_one)時,會爲您的對象動態生成某些方法以方便分配。

現在,您使用的方法是

@contact.guest = @guest 

以及您的聯繫對象能接收另一個ActiveRecord的對象,它可能與自身關聯。你正在嘗試做什麼,在包裝模型對象的窗體中,這種方法很「假」。 (從參數中輸入的信息是以字符串形式輸入的,這就是爲什麼你會得到這個錯誤)

有幾種方法可以執行此操作。第一個是使用嵌套的模型屬性。 。 。複雜的形式,允許你在你正在使用的form_for(使用fields_for表單助手)中包裝一個子關聯。這方面的一個解釋是需要很長時間打字了,幸好有複雜的形式令人難以置信的免費資源:,

Railscasts Complex Forms part 1

Railscasts Complex Forms part 2

Railscasts Complex Forms part 3

此外,如果你正在使用Rails 2.3然後檢查一下「accepts_nested_attributes_for」的一些信息。 。 。現在有一個明顯的缺乏教程,但我想2.3版的發佈將會有很多。這個方便的小助手將刪除Ryan在他的屏幕中使用的大約一半的代碼,以使表單接受一個從屬模型。

最後有一個解決方法。如果你的關係很簡單,如果你想要關聯的客人已經在數據庫中,並且你不需要從你使用的表單創建新的關係,那麼你可以使用類似虛擬屬性的東西。在您的形式,簡單地改變你的f.select :guest爲類似f.select :guest_select和模型實現的方法:

def guest_select=(incoming_id_from_form) 
    contact = Contact.find(incoming_id_from_form) 
    self.guest = contact 
end 

這將分配ActiveRecord的模型,而無需執行復雜的形式來爲你做!

+1

是的。我的用例是解決方案場景......謝謝。 – 2009-05-04 22:30:37

相關問題