2014-02-28 70 views
0

我想合併一個步驟來檢查現有的關係對象作爲我的模型創建/表單提交過程的一部分。例如,假設我有一個Paper型號has_and_belongs_to_many :authors。在我的「創建紙張」表單上,我想要authors_attributes字段爲:name,然後在我的create方法中,首先查找該作者是否存在於「數據庫」中;如果是,則將該作者添加到論文的authors,如果不是,則執行初始化新作者的正常authors_attributes步驟。如何使用first_or_initialize與accept_nested_attributes_for`步驟 - Mongoid

基本上,我想這樣做:

# override authors_attributes 
def authors_attributes(attrs) 
    attrs.map!{ |attr| Author.where(attr).first_or_initialize.attributes } 
    super(attrs) 
end 

但這並不爲許多原因工作(它弄亂了該方法的Mongoid的定義,你可以不包括id_attributes中,除非它已經在型號中註冊)。

我知道處理這些類型情況的首選方法是使用「表單對象」(例如,與Virtus一起)。但是,我有點反對這種模式,因爲它需要重複字段定義和驗證(至少據我瞭解)。

有沒有簡單的方法來處理這種行爲?我覺得它必須是一個常見的情況,所以我必須失去了一些東西......

回答

0

我跟着接受的答案的這個question的建議,並在accepts_nested_attributes_for陳述實施reject_if後衛一樣:

accepts_nested_attributes_for :authors, reject_if: :check_author 

def check_author(attrs) 
    if existing = Author.where(label: attrs['label']).first 
    self.authors << existing 
    true 
    else 
    false 
    end 
end 

這仍然似乎是一個黑客,但它在Mongoid作品,以及...

0

如果我有一個模型Paper

class Paper 
    include Mongoid::Document 

    embeds_many :authors 
    accepts_nested_attributes_for :authors 

    field :title, type: String 
end 

和模型Author嵌入Paper

class Author 
    include Mongoid::Document 

    embedded_in :paper, inverse_of: :authors 

    field :name, type: String 
end 

我可以在控制檯做到這一點:

> paper = Paper.create(title: "My Paper")

> paper.authors_attributes = [ {name: "Raviolicode"} ]

> paper.authors #=> [#<Author _id: 531cd73331302ea603000000, name: "Raviolicode">]

> paper.authors_attributes = [ {id: paper.authors.first, name: "Lucia"}, {name: "Kardeiz"} ]

> paper.authors #=> [#<Author _id: 531cd73331302ea603000000, name: "Lucia">, #<Author _id: 531cd95931302ea603010000, name: "Kardeiz">]

正如你所看到的,我可以更新,並在同一個authors_attributes哈希添加authors

欲瞭解更多信息,請參閱Mongoid nested_attributes article

2

我已經在過去走近這個問題的方法是從某種選擇列表中選擇(無論是大的參考表或選擇一個搜索對話框,允許現有記錄小包裝盒)。包含在對話框或下拉列表中的是創建新參考而不是選取現有項目之一的方法。

使用該方法,您可以檢測記錄是否已存在或是否需要創建。它避免了需要first_or_initialize,因爲用戶的意圖應該從提交給控制器的內容中清楚。

當用戶不想花時間在列表中查找他們想要的內容時,這種方法就會陷入困境。如果發生驗證錯誤,您可以顯示對用戶友好的內容,例如「您是否想要選擇[已有的記錄]?」這也可以幫助一些人。

+0

感謝您的回答。當我需要查找和添加新的作者時,我想我可以做類似'author_ids'和'author_attributes'的單獨字段,但我不知道當它涉及到實際的記錄/關聯時它會發揮多大作用節約過程。我可能會做一些像http://stackoverflow.com/questions/4164185/accepts-nested-attributes-for-to-link-to-existing-record-not-create-a-new-one,雖然它是一種的黑客,我還沒有證實它會與Mongoid一起使用。你的是最好的答案,所以賞金是你的。 –