[Ror-es] HABTM, autoreferencia, y :after_add

Sergio Gil Pérez de la Manga
Mon Feb 27 12:41:48 GMT 2006


Hola,

Soy relativamente novato en RoR, y tengo un error que al menos a mí me
parece bastante inexplicable, a ver si alguien me puede ayudar.

Tengo un modelo con una relación has_and_belongs_to_many sobre sí mismo,
mediante una tabla auxiliar:

class Contact < ActiveRecord::Base

  has_and_belongs_to_many :contacts,
    :join_table => 'known_contacts',
    :foreign_key => 'known_contact_id',
    :association_foreign_key => 'contact_id'

  def known_contacts
    self.contacts
  end
end

El modelo funciona de maravilla, y puedo hacer lo típico:

un_contacto.known_contacts << otro_contacto

He tratado de añadir un filtro :after_add para añadir automáticamente la
relación inversa, como explican aquí [
http://wiki.rubyonrails.com/rails/pages/HowToCreateASelfReferentialManyToManyRelationship
]:

class Contact < ActiveRecord::Base

  has_and_belongs_to_many :contacts,
    :join_table => 'known_contacts',
    :foreign_key => 'known_contact_id',
    :association_foreign_key => 'contact_id',
    :after_add => :create_reverse_association,
    :after_remove => :remove_reverse_association

  def known_contacts
    self.contacts
  end

  private

  def create_reverse_association(contact)
    contact.known_contacts << self unless contact.known_contacts.include?
(self)
  end

  def remove_reverse_association(contact)
    contact.known_contacts.delete(self) if contact.known_contacts.include?
(self)
  end

end

Y bien, parece funcionar, tu metes una relación como puse antes, y se crea
esa, y la inversa. Pero cuando quieres crear una segunda relación para el
mismo contacto, *plonk*

 SQLite::Exceptions::SQLException: PRIMARY KEY must be unique: INSERT
INTO known_contacts ("known_contact_id", "contact_id", "id") VALUES
(3, 2, 2)


Por lo que veo, parece que trata de forzar un valor para el campo id de la
tabla de relaciones, que según he visto en mis pruebas siempre es el id del
contacto en que nos encontramos. Cuando ese id está ocupado (la segunda vez
que añadimos una relación al mismo contacto), no se puede por ser una clave
primaria, que debe ser única lógicamente.

¿A alguien le ha pasado algo parecido? ¿Hay algún error en mi código?
Gracias :)




--
Sergio Gil Pérez de la Manga 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://barclay.textdrive.com/pipermail/ror-es/attachments/20060227/33b5cdc1/attachment.htm