ActiveRecord::AssociationTypeMismatch

Bonjour

J’ai une erreur qui intervient que dans le mode production
ActiveRecord::AssociationTypeMismatch (/var/www/apps/expay/current/
config/…/vendor/rails/activerecord/lib/active_record/associations/
association_proxy.rb:152:in `raise_on_type_mismatch’: CodesPostaux
expected, got Fixnum):

class Distributeur < ActiveRecord::Base
set_table_name “Distributeurs”
set_primary_key “IDDistributeur”

belongs_to :zones, :class_name => "ZonesGraphique", :foreign_key

=> “IDZoneGeographique”
belongs_to :pay, :class_name => “Pay”, :foreign_key => “CodePays”
belongs_to :villes, :class_name => “CodesPostaux”, :foreign_key
=> “IDCodePostal”
end
mon schema
http://pastie.caboo.se/31080

J’ai la dernière version de edge

Merci
Bolo M.
[email protected]
http://blog.developpez.com/index.php?blog=30

Le Jeu 4 janvier 2007 15:49, Bolo M. a écrit :

Bonjour

J’ai une erreur qui intervient que dans le mode production
ActiveRecord::AssociationTypeMismatch (/var/www/apps/expay/current/
config/…/vendor/rails/activerecord/lib/active_record/associations/
association_proxy.rb:152:in `raise_on_type_mismatch’: CodesPostaux
expected, got Fixnum):

Bah, à priori tu tentes simplement d’indiquer un code postal sous forme
numérique là où lui attend un objet de classe CodePostaux.

Tu as peut être dans ton code quelque chose comme :
distribueur.villes = 75011

Par contre, si je peux me permettre, ton code risque de t’apporter
quelques problèmes à terme. Autant que possible tu devrais vraiment tenter
d’utiliser les conventions de nommage Rails.
Je parle autant des correspondance table<->classe que de la question des
pluriels/singulier.

Si tu n’as pas le contrôle sur le schéma de la base je peux comprendre
certaines contorsion mais par exemple tu devrais au moins garder une
bonne
homogénéité sur les règles singulier/pluriel.

Tu as des modèles singuliers (Distributeur, Pay), des modèles pluriels
(CodesPostaux) et des modèles intermédiaires (ZonesGraphique, tu as
d’ailleurs probablement une faute de frappe à cet endroit là).
Rails simplifie aussi beaucoup la vie grace à ses conventions. Là tu
risques de réfléchir à deux fois à chaque utilisation d’un modèle ou d’une
relation, pour vérifier si tu dois utiliser le pluriel ou le singulier.

De même, tu fais une association étrange entre ton modèle (code postaux)
et tes données (villes). Tu risques de complexifier fortement tout ton
développement si les concepts manipulés par ton code ne sont pas ceux
manipulés par tes données. Tu vas devoir faire des conversions implicite
dans ta tête à chaque fois.

Crois moi, tout ça n’a l’air de rien tel quel, mais si ton développement
dure plus de deux semaines ou que tu risques d’en faire de la
maintenance,
ça vaut largement le coup de perdre un ou deux jours pour tout remettre
d’applomb.


Éric Daspet
http://eric.daspet.name/

Bolo :

J’ai une erreur qui intervient que dans le mode production
ActiveRecord::AssociationTypeMismatch
(/var/www/apps/expay/current/config/…/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:152:in
`raise_on_type_mismatch’: CodesPostaux expected, got Fixnum):

Parked at Loopia

A mon avis, tu as des problèmes de clés primaires. Comment les gères-tu
pour les tables CodesPostaux, Distributeurs, Pays, ZonesGraphiques ?

Arrives-tu à faire du CRUD avec ces tables ?
Quel SGBRD utilises-tu ?

-- Jean-François.

Le Jeu 4 janvier 2007 16:15, Bolo M. a écrit :

   @oDists = @oVille.distibuteurs
 end

end

Tu as quoi comme déclaration dans tes modèles de pays, code postaux, zone
et ville ?

Tu entends quoi par association étrange. tu peux m’indiquer ?

belongs_to :villes, :class_name => “CodesPostaux”, :foreign_key =>
“IDCodePostal”

Ici tu dis que :
1- ton Distributeur appartient à une ville unique.
2- les villes listées sont des objets de la classe “CodesPostaux”

Le 1 est étrange vu qu’en même temps tu met “:villes” au pluriel, ce qui
laisses à penser qu’il y a plusieurs villes par distributeur.

Le 2 est au mieux maladroit puisque ça veut dire que tu fais une bijection
entre les villes et les codes postaux. Quand tu demandera
distributeur.villes ça cherchera en fait un code postal et pas une ville.
Bref, ça me parait très étrange comme déclaration de relation.


Éric Daspet
http://eric.daspet.name/

Salut,

Bah, Ã priori tu tentes simplement d’indiquer un code postal sous
forme
numérique là où lui attend un objet de classe CodePostaux.

Tu as peut être dans ton code quelque chose comme :
distribueur.villes = 75011

Ok, mais ce que je comprends pourquoi ca marche en mode devp et pas
en mode production
Pourtant les données sont exactement les meme
La j’attends un string

before_filter :find_all_dist
def index
unless @oPays.blank?
#Création des combos
@oZones = @oPays[0].zones
@oVilles = @oZones[0].villes
#Les Variables
@region = “Département”
@sous_region = “Ville”
@oVille = @oZones[0].villes[0]
#La liste des distributeurs par villes
@oDists = @oVille.distibuteurs
end
end

Par contre, si je peux me permettre, ton code risque de t’apporter
quelques problèmes à terme. Autant que possible tu devrais vraiment
tenter
d’utiliser les conventions de nommage Rails.

Oui mais je ne pouvais pas faire autrement. Je ne choisis pas les nom
des tables et des attributs

ou d’une
relation, pour vérifier si tu dois utiliser le pluriel ou le
singulier.

D’accord je vais corriger tout ca

De même, tu fais une association étrange entre ton modèle (code
postaux)
et tes données (villes). Tu risques de complexifier fortement tout ton
développement si les concepts manipulés par ton code ne sont pas ceux
manipulés par tes données. Tu vas devoir faire des conversions
implicite
dans ta tête à chaque fois.

Tu entends quoi par association étrange. tu peux m’indiquer ?

Merci pour tes réponses


Éric Daspet
http://eric.daspet.name/


Railsfrance mailing list
[email protected]
http://lists.rubyonrails.fr/mailman/listinfo/railsfrance

Bolo M.
[email protected]
http://blog.developpez.com/index.php?blog=30

Le 4 janv. 07 à 11:15, Jean-François a écrit :

gères-tu
pour les tables CodesPostaux, Distributeurs, Pays, ZonesGraphiques ?

Ce que je n’arrive pas à saisir c’est pourquoi ca ne passe pas que en
Production
voila mes migrations

class CreatePays < ActiveRecord::Migration
def self.up
create_table :Pays, :id => false, :primary_key => ‘CodePays’ do |t|
t.column :CodePays, :string
t.column :LibelleFr, :string
t.column :EstActif, :integer
end
end

def self.down
drop_table :Pays
end
end

class CreateZonesGraphiques < ActiveRecord::Migration
def self.up
create_table :ZonesGraphiques, :id => false, :primary_key =>
‘IDZoneGeographique’ do |t|
t.column :IDZoneGeographique, :integer
t.column :CodeZone, :string
t.column :Libelle, :string
t.column :CodePays, :string
end
end

def self.down
drop_table :ZonesGraphiques
end
end

class CreateCodesPostauxes < ActiveRecord::Migration
def self.up
create_table :CodesPostaux, :id => false, :primary_key =>
‘IDCodePostal’ do |t|
t.column :IDCodePostal, :integer
t.column :IDZoneGeographique, :integer
t.column :CodePostal, :string
t.column :ville, :string
end
end

def self.down
drop_table :CodesPostaux
end
end

class CreateDistributeurs < ActiveRecord::Migration
def self.up
create_table :Distributeurs, :id => false, :primary_key =>
‘IDDistributeur’ do |t|
t.column :IDDistributeur, :integer
t.column :CodeDistributeur, :integer
t.column :RaisonSociale, :string
t.column :AdresseL1, :string
t.column :AdresseL2, :string
t.column :Longitude, :float
t.column :Latitude, :float
t.column :IDCodePostal, :integer
t.column :IDZoneGeographique, :integer
t.column :CodePays, :string
end
end

def self.down
drop_table :Distributeurs
end
end

Arrives-tu à faire du CRUD avec ces tables ?

C’est à dire

Quel SGBRD utilises-tu ?

Pour l’instant je n’utilise que sqlite. J’attends que tout ca marque
et apres je utiliser au final un base MS SQL Server 2005

РJean-Fran̤ois.


À la renverse.


Railsfrance mailing list
[email protected]
http://lists.rubyonrails.fr/mailman/listinfo/railsfrance

Bolo M.
[email protected]
http://blog.developpez.com/index.php?blog=30

Bolo :

Tu as quoi comme déclaration dans tes modèles de pays, code
postaux, zone et ville ?

J’ai refais model en suivant tes indications

class Pay < ActiveRecord::Base

Puisque tu es en plein retoilettage, profites-en pour demander Ã
Inflector
de traiter ‘pays’ comme nom invariable (Inflections, cf archives de la
liste)

set_table_name “Pays”
set_primary_key “CodePays”

has_many :distibuteurs,

ya une tite typo : “distributeurs”, profitons-en pour corriger les
fautes
d’orthographe

       :class_name => "Distributeur",
       :foreign_key => "CodePays"

has_many :zones, :through => :distibuteurs,

pareil

:select => “Distinct ZonesGraphiques.*”

Et puis aussi :

   @oVille = @oZones[0].villes[0]

t’as quand même le choix des noms des variables, si ?

@ville ou @ma_ville, c’est pas plus simple ?

je suppose que @oZones (ah, c’était pour le jeu de mot ?)
est un tableau :

@ville = @zones.first.villes.first

c’est pas plus clair, plus lisible, donc plus facilement maintenable ?

-- Jean-François.

Tu as quoi comme déclaration dans tes modèles de pays, code
postaux, zone
et ville ?

J’ai refais model en suivant tes indications

class Pay < ActiveRecord::Base

set_table_name “Pays”
set_primary_key “CodePays”

has_many :distibuteurs,
:class_name => “Distributeur”,
:foreign_key => “CodePays”

has_many :zones, :through => :distibuteurs, :select => “Distinct
ZonesGraphiques.*”

def self.find_with_dist
find(:all, :readonly => false,
:select => "DISTINCT Pays.LibelleFr,
Pays.CodePays, Pays.EstActif ",
:order => ‘LibelleFr’,
:joins => “INNER JOIN Distributeurs e ON
Pays.CodePays = e.CodePays”)
end
end

class CodePostal < ActiveRecord::Base

set_table_name “CodesPostaux”
set_primary_key “IDCodePostal”

has_many :distibuteurs,
:class_name => “Distributeur”,
:foreign_key => “IDCodePostal”

has_many :zones, :through => :distibuteurs, :select => “Distinct
Codes_Postaux.*”
end

class ZoneGraphique < ActiveRecord::Base

set_primary_key “IDZoneGeographique”
set_table_name “ZonesGraphiques”

has_many :distibuteurs,
:class_name => “Distributeur”,
:foreign_key => “IDZoneGeographique”

has_many :villes, :through => :distibuteurs
end

Il n’y a pas de model ville

Tu entends quoi par association étrange. tu peux m’indiquer ?

belongs_to :villes, :class_name => “CodesPostaux”, :foreign_key =>
“IDCodePostal”

Ici tu dis que :
1- ton Distributeur appartient à une ville unique.
2- les villes listées sont des objets de la classe “CodesPostaux”

ville.
Bref, ça me parait très étrange comme déclaration de relation.

En fait pour être clair j’aurais du remplacé villes par code_postal.

Quand tu demandera
distributeur.villes ça cherchera en fait un code postal et pas une
ville.
Bref, ça me parait très étrange comme déclaration de relation

C’est tout à fait ca


Éric Daspet
http://eric.daspet.name/


Railsfrance mailing list
[email protected]
http://lists.rubyonrails.fr/mailman/listinfo/railsfrance

Bolo M.
[email protected]
http://blog.developpez.com/index.php?blog=30

Le Jeu 4 janvier 2007 16:21, Bolo M. a écrit :

Ce que je n’arrive pas à saisir c’est pourquoi ca ne passe pas que en
Production

La seule chose qui change en production pour ce qui nous concerne ici
c’est que le schéma de la base n’est pas redécouvert à chaque requête.
Tentes de redémarrer le rails de ta production.


Éric Daspet
http://eric.daspet.name/

Bolo :

Parked at Loopia

A mon avis, tu as des problèmes de clés primaires. Comment les gères-tu
pour les tables CodesPostaux, Distributeurs, Pays, ZonesGraphiques ?

Ce que je n’arrive pas à saisir c’est pourquoi ca ne passe pas que en
Production
voila mes migrations
[snip]

create_table :Pays, :id => false, :primary_key => ‘CodePays’ do |t|
create_table :ZonesGraphiques, :id => false, :primary_key =>
‘IDZoneGeographique’ do |t|
create_table :CodesPostaux, :id => false, :primary_key => ‘IDCodePostal’
create_table :Distributeurs, :id => false, :primary_key => ‘IDDistributeur’

Il est inutile de dire à Rails que la clé primaire s’appelle untel si tu
lui
demandes de ne pas la créer.

Et si ta table n’a pas d’entier auto-incrémenté (MySQL) comme clé
primaire (pk) ni de serial (PostgreSQL) comme pk et si tu ne gères
pas cette colonne à la place de Rails, je sais pas comment ça peut
marcher. C’est à mon avis (pas eu à traiter ce cas de figure), mais
ça nécessite un peu de boulot (à coup de before_save sûrement).

Arrives-tu à faire du CRUD avec ces tables ?

C’est à dire

créer, mettre à jour, effacer, récupérer des enregistrements via
ActiveRecord,
a priori sans gestion de clé primaire ?

c’est une occasion pour écrire des tests unitaires, tiens.

Quel SGBRD utilises-tu ?

Pour l’instant je n’utilise que sqlite. J’attends que tout ca marque et
apres je utiliser au final un base MS SQL Server 2005

Mmmhh, Ã ta place je blinderais les tests.

РJean-Fran̤ois.

Le 4 janv. 07 à 12:01, Jean-François a écrit :

de traiter ‘pays’ comme nom invariable (Inflections, cf archives de
la liste)

Ok j’ai rajouté
inflect.irregular(‘pays’, ‘pays’)

Voila ma nouvelle table
class Pays < ActiveRecord::Base

set_table_name “Pays”
set_primary_key “CodePays”

has_many :distributeurs,
:class_name => “Distributeur”,
:foreign_key => “CodePays”

has_many :zones, :through => :distributeurs, :select => “Distinct
ZonesGraphiques.*”

def self.find_with_dist
find(:all, :readonly => false,
:select => "DISTINCT Pays.LibelleFr,
Pays.CodePays, Pays.EstActif ",
:order => ‘LibelleFr’,
:joins => “INNER JOIN Distributeurs e ON
Pays.CodePays = e.CodePays”)
end
end

t’as quand même le choix des noms des variables, si ?

@ville ou @ma_ville, c’est pas plus simple ?

je suppose que @oZones (ah, c’était pour le jeu de mot ?)
est un tableau :

C’est habitude que j’ai appris en développant en AS
la première lettre de la variable est en minuscule et elle correspond
au type ou ce qu’elle représente
Donc la c’est des objets mais bon ruby comme tout est objet …
Si la variable contenait un nombre j’aurais vais

nCode_Postal


Railsfrance mailing list
[email protected]
http://lists.rubyonrails.fr/mailman/listinfo/railsfrance

Bolo M.
[email protected]
http://blog.developpez.com/index.php?blog=30

Le 4 janv. 07 à 13:04, Eric D. a écrit :

A vérifier mais je crois bien que Rails accepte aussi les chaînes
pour les
clés primaires. C’est juste qu’il ne pourra pas s’en occuper tout seul
lors des créations.

J’ai regardé dans le bouquin Ruby on Rails. Je crois qu’il peut
utiliser les strings en clef primaires


Éric Daspet
http://eric.daspet.name/


Railsfrance mailing list
[email protected]
http://lists.rubyonrails.fr/mailman/listinfo/railsfrance

Bolo M.
[email protected]
http://blog.developpez.com/index.php?blog=30

Le Jeu 4 janvier 2007 17:24, Jean-Francois a écrit :

Rails utilise des entiers comme cle primaire, la CodePostal
est une String, m’est avis que ca va peter a un moment.
D’ailleurs c’est ce qui s’est passe.

Rails utilise des entiers comme clé primaire, là CodePostal
est une String, m’est avis que ça va péter à un moment.
D’ailleurs c’est ce qui s’est
passé.

A vérifier mais je crois bien que Rails accepte aussi les chaînes pour les
clés primaires. C’est juste qu’il ne pourra pas s’en occuper tout seul
lors des créations.


Éric Daspet
http://eric.daspet.name/

Le 4 janv. 07 à 11:41, Eric D. a écrit :

Le Jeu 4 janvier 2007 16:21, Bolo M. a écrit :

Ce que je n’arrive pas à saisir c’est pourquoi ca ne passe pas que en
Production

La seule chose qui change en production pour ce qui nous concerne ici
c’est que le schéma de la base n’est pas redécouvert à chaque requête.
Tentes de redémarrer le rails de ta production.

J’ai relancé mongrel plusieurs fois cependant j’ai le meme chose


Éric Daspet
http://eric.daspet.name/


Railsfrance mailing list
[email protected]
http://lists.rubyonrails.fr/mailman/listinfo/railsfrance

Bolo M.
[email protected]
http://blog.developpez.com/index.php?blog=30

Le 4 janv. 07 à 12:24, Jean-François a écrit :

  t.column :LibelleFr, :string
  t.column :EstActif, :integer
end

.column :CodePays, :string

cette ligne n’indique pas que je demande de la crée non ?

Rails va te créer la colonne ‘CodePays’ oui (tiens c’est Rails qui
est chargé de créer les tables de la base, mais pas de les remplir),
ce sera une colonne comme les autres.

Oui Parce que la je suis en d’utiliser SQLITE donc je fais mes propre
migration mais quand je tout fonctionne je passerais sous SQL Server

Pour en revenir au :
:id => false, :primary_key => ‘CodePays’

Imagine que je dise “Je n’ai pas de chien, il s’appelle Médor”,
ça n’as pas de sens. Ben là , c’est un peu pareil.

Je pensais que ca voulait dire

1 Ne crée pas automatiquement d’attribut id
2. la clé primaire est CodePays

J’avais trouvé cette syntaxe dans ce thread
http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/
b8673a8a0933b1e0/889409a2330540d4?lnk=gst&q=%3Aid+%3D%3E+false%2C+%
3Aprimary_key+%3D%3E&rnum=1#889409a2330540d4

oui, mais où ça ? pas vu de code dans ton appli qui s’en occupe.
Nos mails se croisent c’est pour ca,
Il y a une autre application qui est windev. Celle ci s’occupe
d’alimenter la base de données

Pour l’instant j’ajoute mes enregistrement manuellement dans ma bdd
Sqlite

Rails ne fait que lire les enregistrements de la table.

ça simplifie les choses, ça fait des soucis en moins.
Et ça marche bien pour les associations ?

Tout fonctionne en mode dev d’où mon incompréhension
Si Rails ne supporte pais les clé primaires string comment peut on
faire alors

A+

РJean-Fran̤ois.


À la renverse.


Railsfrance mailing list
[email protected]
http://lists.rubyonrails.fr/mailman/listinfo/railsfrance

Bolo M.
[email protected]
http://blog.developpez.com/index.php?blog=30

Le 4 janv. 07 à 11:43, Jean-François a écrit :

[snip]
si tu lui
demandes de ne pas la créer.

Mais quand je fais ca

 create_table :Pays, :id => false, :primary_key => 'CodePays' do |t|
   t.column :CodePays, :string
   t.column :LibelleFr, :string
   t.column :EstActif, :integer
 end

.column :CodePays, :string

cette ligne n’indique pas que je demande de la crée non ?

Et si ta table n’a pas d’entier auto-incrémenté (MySQL) comme clé
primaire (pk) ni de serial (PostgreSQL) comme pk et si tu ne gères
pas cette colonne à la place de Rails, je sais pas comment ça peut
marcher.
Si les clé primaires qui ne pas gérer rails, je les gères moi même.
Rails ne fait que lire les enregistrements de la table. Une autre
application (qui n’est pas de moi ) fais les autres opérations
Ajout, modification et Suppression

Arrives-tu à faire du CRUD avec ces tables ?

C’est à dire

créer, mettre à jour, effacer, récupérer des enregistrements via
ActiveRecord,
a priori sans gestion de clé primaire ?

Pour l’instant ca marche en mode dev puisque que j’arrive à lire mes
enregistrements

Quel SGBRD utilises-tu ?

Pour l’instant je n’utilise que sqlite. J’attends que tout ca
marque et
apres je utiliser au final un base MS SQL Server 2005

Mmmhh, Ã ta place je blinderais les tests.

Cette partie va être galère galère, ca enfin me forcer a utiliser les
test

Bolo :

.column :CodePays, :string

cette ligne n’indique pas que je demande de la crée non ?

Rails va te créer la colonne ‘CodePays’ oui (tiens c’est Rails qui
est chargé de créer les tables de la base, mais pas de les remplir),
ce sera une colonne comme les autres.

Pour en revenir au :
:id => false, :primary_key => ‘CodePays’

Imagine que je dise “Je n’ai pas de chien, il s’appelle Médor”,
ça n’as pas de sens. Ben là , c’est un peu pareil.

Et si ta table n’a pas d’entier auto-incrémenté (MySQL) comme
clé primaire (pk) ni de serial (PostgreSQL) comme pk et si tu ne
gères pas cette colonne à la place de Rails, je sais pas comment
ça peut marcher.

Si les clé primaires qui ne pas gérer rails, je les gères moi même.

“si les clés primaires ne sont pas gérer par Rails, je les gère
moi-même”
oui, mais où ça ? pas vu de code dans ton appli qui s’en occupe.

Rails ne fait que lire les enregistrements de la table.

ça simplifie les choses, ça fait des soucis en moins.
Et ça marche bien pour les associations ?

Rails utilise des entiers comme clé primaire, là CodePostal
est une String, m’est avis que ça va péter à un moment.
D’ailleurs c’est ce qui s’est passé.

Pour l’instant ca marche en mode dev puisque que j’arrive à lire mes
enregistrements

même les associations ça marche ?

РJean-Fran̤ois.

Le Jeu 4 janvier 2007 17:34, Bolo M. a écrit :

Pour en revenir au :
:id => false, :primary_key => ‘CodePays’

Je pensais que ca voulait dire

1 Ne crée pas automatiquement d’attribut id
2. la clé primaire est CodePays

Oui
En fait c’est plutot comme dire “Pas besoin de venir chez moi. Pour
venir
chez moi tu dois tourner à gauche au prochain feu”.

Disons que le :primary_key => ‘CodePays’ ne sert que pour créer la clé
primaire. Si tu lui demandes en même temps de ne pas la créer, ça fait un
peu superflue. Ca ne peut pas faire de mal, ceci dit.


Éric Daspet
http://eric.daspet.name/