如何在Rails ActiveRecord中创建,关联和取消关联相关记录与accepts_nested_attributes_for

时间:2011-01-07 01:24:56

标签: ruby-on-rails ruby-on-rails-3 activerecord associations

我在两个模型之间有一个典型的has_many关系(比如文章has_many作者。)

我的文章表单允许用户:

  1. 创建新作者并将其与文章相关联,
  2. 选择要与文章相关联的现有作者
  3. 删除与作者的关联(不删除作者记录。)
  4. 我正在使用accepts_nested_attributes_for,这完全处理#1。但是,我还没有找到实现#2和#3的最佳方法,同时仍然使用accepts_nested_attributes_for。

    我实际上已经将这一切都与Rails 3.0.0一起使用了。 ActiveRecord会在给定之前未曾见过的作者ID时自动创建新关联。但事实证明我无意中利用了随后在Rails 3.0.1中修复的安全漏洞。

    我尝试了很多不同的方法,但没有任何方法可以完全发挥作用,在这种情况下我找不到关于最佳实践的更多信息。

    任何建议都会受到赞赏。

    谢谢,

    罗素。

3 个答案:

答案 0 :(得分: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 :(得分:1)

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

它用于rails 2.3,但大多数语法与rails3相同...它提到了你要找的所有东西..

答案 2 :(得分: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

我还没有找到一种方法来验证相关模型(作者)的验证..