This is probably the best way to do this, but it concerns what I can come up with now.
The has_many (: through) association accepts_nested_arguments_for uses a virtual attribute assignment #{association}_attributesto work with magic. It expects an array of hashes, where each hash contains attribute keys and their values. Any hashes with an identifier will be updated (or deleted if there is a key :_deletewith a value of true). Any hashes that do not have an identifier will be used to create new elements of this association. Thus, the key is to intercept the call tags_associations=and check any hashes that do not have identifiers for an existing tag with the same name, and replace it with the entry that attribute_tags will use to link the existing tag, NB has_one belongs_to tag_attributes . , .
class Thing < ActiveRecord::Base
has_many :tags, :through => :taggings
has_many :taggings
accepts_nested_attributes_for :tags
def tags_attributes_with_recycling=(attributes)
existing_attributes = attributes.reject{|attribute| attribute[:id].nil?}
new_attributes = attributes - existing_attributes
new_and_recycled_attributes = new_attributes.map { |attribute|
tag_id = Tag.find_by_name(attribute[:name]).id
tag_id ? {:id => tag_id) : attribute
}
tags_attributes_without_recycling= (existing_attributes + new_and_recycled_attributes)
end
alias_method_chain :tags_attributes=, :recycling
end
, . .