2011-01-07 90 views
4

我有兩個型號之間的典型的has_many關係(可以說文章的has_many作者。)如何創建,在Rails的ActiveRecord的關聯,和去關聯的相關記錄與accepts_nested_attributes_for

我的文章的形式讓用戶:

  1. 創建新的作者,並將其與關聯條,
  2. 選擇現有的作者與關聯條,
  3. 刪除與作者的關係(但不刪除作者的記錄。)

我正在使用accep_nested_attributes_for,這完全處理#1。但是,我還沒有找到實現#2和#3同時仍然使用accep_nested_attributes_for的最佳方式。

我實際上已經全部使用Rails 3.0.0。當給定一個它以前沒有見過的Author ID時,ActiveRecord會自動創建一個新的關聯。但事實證明,我意外地利用了在Rails 3.0.1中修復的安全漏洞。

我已經嘗試了一堆不同的方法,但沒有完全工作,在這種情況下我找不到有關最佳實踐的很多信息。

任何意見將不勝感激。

謝謝,

羅素。

+0

您在使用連接表(HABTM)嗎?我認爲作者也可以有許多文章。如果你在每種情況下都包括來自你的表單的參數,這也會很有幫助。 – aceofspades 2012-12-11 18:41:38

回答

1

看看這個:http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes

其軌道2.3,但大部分的語法與Rails3中一樣......它提到你看..

+0

謝謝,但Ryan的帖子只是解釋了accep_nested_attributes_for的工作原理。它沒有解釋#2(選擇現有作者與本文關聯)或#3(刪除與作者的關聯而不刪除作者記錄。) – 2011-01-07 20:30:30

+0

一個想法:你應該有一個have_and_belongs_to_many或has_many:through關係,因爲一個作者可以有多個文章,一個文章可以有多個作者。一個正常的has_many關係不會是正確的關係模式。 – Lichtamberg 2011-01-09 13:58:20

2

所有的東西。假設你可能需要使用一個連接表。這給一展身手:

class Article < ActiveRecord::Base 
    has_many :article_authors 
    accepts_nested_attributes_for :article_authors, allow_delete: true 
end 

class Author < ActiveRecord::Base 
    has_many :article_authors 
end 

class ArticleAuthor < ActiveRecord::Base 
    belongs_to :article 
    belongs_to :author 
    accepts.nested_attributes_for :author 
end 


# PUT /articles/:id 
params = { 
    id: 10, 
    article_authors_attributes: { 
    [ 
     # Case 1, create and associate new author, since no ID is provided 
     { 
     # A new ArticleAuthor row will be created since no ID is supplied 
     author_attributes: { 
      # A new Author will be created since no ID is supplied 
      name: "New Author" 
     } 
     } 

    ], 
    [ 
     # Case 2, associate Author#100 
     { 
     # A new ArticleAuthor row will be created since no ID is supplied 
     author_attributes: { 
      # Referencing the existing Author#100 
      id: 100 
     } 
     } 
    ], 
    [ 
     # Case 3, delete ArticleAuthor#101 
     # Note that in this case you must provide the ID to the join table to delete 
     { 
     id: 1000, 
     _destroy: 1 
     } 
    ] 
    } 
} 
1

爲了完整起見,現在我這樣做的方式是這樣的:

class Article < ActiveRecord::Base 
    belongs_to :author, validate: false 
    accepts_nested_attributes_for :author 

    # This is called automatically when we save the article 
    def autosave_associated_records_for_author 
    if author.try(:name) 
     self.author = Author.find_or_create_by_name(author.name) 
    else 
     self.author = nil # Remove the association if we send an empty text field 
    end 
    end 

end 

class Author < ActiveRecord::Base 
    has_many :articles 
end 

我還沒有找到一種方法來驗證相關模型(作者)與它的驗證..