AssociationTypeMismatch

Hola,

Tengo un problema con

ActiveRecord::AssociationTypeMismatch: Mac expected, got String

La doc en ActiveRecord::Associations::ClassMethods es un poco escueta
al respecto:

===
Type safety with ActiveRecord::AssociationTypeMismatch

If you attempt to assign an object to an association that doesn’t
match the inferred or specified :class_name, you’ll get a
ActiveRecord::AssociationTypeMismatch.

Por qué infiere “Mac” i no String ? Al fin y al cabo en la BBDD hay
una string que representa una mac y sólo quiero que los trate como
strings :-S… los modelos afectados tienen este aspecto:

== Schema Information

Schema version: 7

Table name: ips

id :integer(11) not null, primary key

ip :string(255)

mac :string(255)

zone_id :integer(11)

mac_id :integer(11)

class Ip < ActiveRecord::Base
has_one :mac

== Schema Information

Schema version: 8

Table name: macs

id :integer(11) not null, primary key

mac :string(255)

oid :string(255)

system_id :integer(11)

port_id :integer(11)

ip_id :integer(11)

class Mac < ActiveRecord::Base
has_many :ips

TIA !

Perdon, tenia el rake annotate_models desactualizado:

== Schema Information

Schema version: 9

Table name: ips

id :integer(11) not null, primary key

ip :string(255)

mac :string(255)

zone_id :integer(11)

== Schema Information

Schema version: 9

Table name: macs

id :integer(11) not null, primary key

mac :string(255)

oid :string(255)

system_id :integer(11)

port_id :integer(11)

ip_id :integer(11)

Las associations si que estan correctas. Y parte del backtrace:

/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations/association_proxy.rb:134:in
raise_on_type_mismatch' /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations/has_one_association.rb:44:inreplace’
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:850:in
mac=' /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:1510:insend’
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:1510:in
`attributes=’

Gracias… por cierto, es sólo mi impresión o va un poco demasiado
lento al entregar mails a la lista vuestro mailman ?

El Sunday 18 March 2007 23:01:48 brainstorm escribió:

Type safety with ActiveRecord::AssociationTypeMismatch

If you attempt to assign an object to an association that doesn’t
match the inferred or specified :class_name, you’ll get a
ActiveRecord::AssociationTypeMismatch.

Por qué infiere “Mac” i no String ? Al fin y al cabo en la BBDD hay
una string que representa una mac y sólo quiero que los trate como
strings :-S… los modelos afectados tienen este aspecto:

Precisamente se está quejando de que esperaba que fuera un Mac y no un
String.
Supongo que, siendo ‘ip’ una instancia de Ip, estás tratando de hacer
algo
como:

ip.mac = una_mac

Donde ‘una_mac’ es realmente una cadena, no una instancia de Mac.

¿Se entiende?

Saludos.


Imobach González Sosa
correo-e: imobachgs en banot punto net
jabber id: osoh en jabberes punto org
web: banot.net
blog: http://devnull.blogs.banot.net/

On Mar 19, 2007, at 1:02 AM, brainstorm wrote:

zone_id :integer(11)

Ahi hay algo raro, porque una IP has_one :mac, y a la vez tiene un
campo “mac”, de manera que de entrada hay un conflicto de nombres
porque has_one genera el accessor #mac, lo mismo que la existencia de
la columna. Por otro lado, dado que una mac has_many :ips, en la
tabla :ips se deberian guardar las mac_id, no las cadenas.

– fxn

Hola,

No me creo que mi “apaño” sea la única forma de solucionarlo… rails no
es
capaz de saber actualizar de atributo_id (en este caso mac_id)
automáticamente ? Me explico bien ?

Gracias por avanzado !
Roman

Ok, hoy me he vuelto a poner con el tema, os comento cómo lo he
solventado:

def update
@ip = Ip.find(params[:id])

  • @ip.mac_id = Mac.find_by_mac(params[:ip][:mac]).id
  • if @ip.update_attributes(params[:ip])
  • if @ip.update_attribute(‘ip’, params[:ip][:ip])
    flash[:notice] = ‘Ip was successfully updated.’

Ahí van preguntas, porque no me convence nada este código:

  1. En el primer añadido… no hay una forma más railera de hacerlo ?
    Por ejemplo,
    que automágicamente determine que mac es del modelo Mac y actualice
    mac_id de Ip ?

  2. Misma pregunta sobre la otra modificación (este era precisamente el
    motivo del error),
    he actualizado el schema (gracias Xavier):

== Schema Information

Schema version: 10

Table name: ips

id :integer(11) not null, primary key

ip :string(255)

mac_id :integer(11)

zone_id :integer(11)

Gracias a los dos como siempre ! :slight_smile:

On Mar 28, 2007, at 1:12 AM, brainstorm wrote:

No me creo que mi “apaño” sea la única forma de solucionarlo…
rails no es
capaz de saber actualizar de atributo_id (en este caso mac_id)
automáticamente ? Me explico bien ?

Rails ofrece una buena abstraccion sobre el manejo de relaciones, es
muy pero que muy raro que debas tocar un ID a mano usando los idiomas
correctos. Casualmente Jamis B. hizo un post con unos cuantos ayer:

http://www.therailsway.com/2007/3/26/association-proxies-are-your-
friend

En general, si te ves usando un campo que tiene una llave foranea a
mano, warning!

Por otro lado, recuerda que en el codigo que enviaste hay dos metodos
que se llaman igual y por tanto sus definiciones se pisan.

– fxn

On Mar 28, 2007, at 10:03 AM, Xavier N. wrote:

muy pero que muy raro que debas tocar un ID a mano usando los idiomas
correctos. Casualmente Jamis B.

Hmm, no fue Jamis en este caso :-).

– fxn