简体   繁体   中英

How can I create, associate, and de-associate related records in Rails ActiveRecord with accepts_nested_attributes_for

I have a typical has_many relationship between two models (lets say Article has_many Authors.)

My Article form lets the user:

  1. Create new Authors and associate them with the Article,
  2. Select existing Authors to associate with the Article,
  3. Remove the association with an Author (without deleting the Author record.)

I am using accepts_nested_attributes_for and this handles #1 perfectly. However, I am yet to find the best way of implementing #2 and #3 while still using accepts_nested_attributes_for.

I actually had this all working with Rails 3.0.0. ActiveRecord would automatically create a new association when given an Author id that it had not seen before. But it turned out I was accidentally exploiting the security bug that was then fixed in Rails 3.0.1.

I've tried a bunch of different approaches, but nothing works completely and I can't find much information on best practices in this case.

Any advice would be appreciate.

Thanks,

Russell.

Assuming you probably need to use a join table. Give this a go:

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
      }
    ]
  }
}

For completeness, the way I'm doing this now is this:

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

I haven't found a way to validate the associated model (Author) with it's validations..

Look at this: http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes

its for rails 2.3, but most of the syntax is the same with rails3... It mentions all things you look for..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM