views:

27

answers:

1

I'm using Rails' accepts_nested_attributes_for method with great success, but how can I have it not create new records if a record already exists?

By way of example:

Say I've got three models, Team, Membership, and Player, and each team has_many players through memberships, and players can belong to many teams. The Team model might then accept nested attributes for players, but that means that each player submitted through the combined team+player(s) form will be created as a new player record.

How should I go about doing things if I want to only create a new player record this way if there isn't already a player with the same name? If there is a player with the same name, no new player records should be created, but instead the correct player should be found and associated with the new team record.

A: 

When you define a hook for autosave associations, the normal code path is skipped and your method is called instead. Thus, you can do this:

class Post < ActiveRecord::Base
  belongs_to :author, :autosave => true
  accepts_nested_attributes_for :author

  # If you need to validate the associated record, you can add a method like this:
  #     validate_associated_record_for_author
  def autosave_associated_record_for_author
    # Find or create the author by name
    if new_author = Author.find_by_name(author.name) then
      self.author = new_author
    else
      self.author.save!
    end
  end
end

This code is untested, but should be pretty much what you need.

François Beausoleil
Can you please point this functionality in the documentation?
dombesz
Also i think the correct is def autosave_associated_records_for_author.
dombesz
Is this method works on the other side of the relation? for example what if we have has_many :authors ?
dombesz
I can't find it anywhere in the docs, but it's very clear from the code it's supposed to be overriden: http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html and http://github.com/rails/rails/blob/2-3-stable/activerecord/lib/active_record/autosave_association.rb#L168
François Beausoleil
thanks for the source link
dombesz