I am having a similar problem.
Except I haven''t tested it out because the project was put on hold for
another project... I have a habtm association (on each end of the
habtm) and without even having the controller actions to change
anything but the number of times one of the habtm-ed models has been
viewed (ie: this haiku has been read 15 times) all of the habtm
associations get doubled.
I''m not even sure when it happens (because i haven''t tested
it) but
some time after checking to see if the association importation worked
all the associations are doubled (ie: a haiku with a tag of summer now
has two tags, summer and summer).
If I get some time I''ll try and uncover when it is occuring.
-Caleb
On 5/23/05, François Beausoleil <fbeausoleil-IQIa899fVSs@public.gmane.org>
wrote:> Hi !
>
> (See references at the end)
>
> I have a slight problem. Whenever I save one of my domain models, which
> contains an has_and_belongs_to_many relationship with another one, the
> relationships are doubled.
>
> My domain is a series of pictures, where each picture can be tagged with
> one or more words. So, a picture of my dog could be tagged "Jordy,
Dog,
> Dog 2005", for example.
>
> In my form, the tags are presented to the user in a single INPUT
> type="text". The user edits the list, and separates the words
using a
> comma.
>
> Then, my controller splits everything back, and asks the Picture domain
> object to update it''s tags.
>
> The implementation is at the bottom, but the end result is that I get
> two rows like this:
>
> INSERT INTO pictures_tags(picture_id, tag_id) VALUES (13, 21);
> INSERT INTO pictures_tags(picture_id, tag_id) VALUES (13, 21);
>
> If I add a unique index to pictures_tags, MySQL rejects the second
> insert, as it should.
>
> The only way I found to prevent that problem is to save my picture
> first, and then to update the tags.
>
> Is that behavior expected ? What am I doing wrong ? Should
> has_and_belongs_to_many be defined on both domain objects ?
>
> Thanks for any tips !
> François
>
> R E F E R E N C E S
> ==================>
> SQL Tables
> ----------
> create table pictures (
> id int primary key auto_increment,
> title varchar(80)
> );
>
> create table tags (
> id int primary key auto_increment,
> tag varchar(32)
> );
>
> Domain objects
> --------------
> class Picture < ActiveRecord::Base
> has_and_belongs_to_many :tags
>
> def update_tags(tags)
> tags = tags.collect! {|name| name.downcase}
> reject_invalid_tags(tags)
> remove_deleted_tags(tags)
> reject_existing_tags(tags)
> add_tags_to_picture(tags)
> end
>
> protected
> def reject_invalid_tags(tags)
> tags.reject! { |name| name.nil? or name.empty? }
> end
>
> def remove_deleted_tags(tags)
> self.tags.each {|tag|
> self.tags.delete(tag) unless tags.include?(tag.tag)
> }
> end
>
> def reject_existing_tags(tags)
> self.tags.each { |tag| tags.delete tag.tag.downcase }
> end
>
> def add_tags_to_picture(tags)
> tags.each do |name|
> tag = Tag.find_by_tag(name.downcase) ||
> Tag.create(''tag'' => name.downcase)
> self.tags.push(tag)
> end
> end
> end
>
> class Tag < ActiveRecord::Base
> has_and_belongs_to_many :pictures
>
> def to_s() self.tag.capitalize end
> def ==(other) return self.tag == other.tag end
> def <=>(other) return self.tag <=> other.tag end
> end
>
> Controller
> ----------
> class PhotoController < ApplicationController
> def save
> pict = @params[''picture'']
>
> picture = Picture.new
> picture.original = main_image
> picture.title = pict[''title'']
> picture.body = pict[''body'']
> picture.author = author
>
> # Adding these lines prevents the problem from
> # occuring:
> # picture.save
> # picture.reload
>
>
picture.update_tags(pict[''tags''].split(/\s*,\s*/))
> picture.save
> end
> end
>
> _______________________________________________
> Rails mailing list
> Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>