Comportements bizarres

bonjour,

j’ai rencontré des comportements assez bizarres, et j’aimerais vous en
faire part.

j’ai deux objets User et Member, avec les relations User belongs_to
Member et Member has_one user. j’ai le code suivant au niveau de mon
controlleur :

protected
def get_member
@user = current_user
if @user.member
@member = @user.member
else
@member = Member.new
@member.user = @user
@member.save!
@user.member = @member
@user.save!

  end
end

le problème c’est qu’à la création du membre, le member_id au niveau de
users est bien renseigné mais pas le user_id dans members… par contre
si je transforme la relation Member => User en belongs_to, cela
fonctionne bien !!

autre comportement étrange, lorsque je définis la méthode de validation
suivante dans Member :

def validate
if zip_code && ! ( zip_code.to_s =~ /^\d+( \d+)?$/ )
errors.add(:zip_code, “is invalid”)
end
end

tout est accepté !

j’avoue être un peu déconcerté. si vous pouvez m’éclairer, j’en serais
ravi :slight_smile:

merci

julien

le problème c’est qu’à la création du membre, le member_id au niveau de
users est bien renseigné mais pas le user_id dans members…

il me semble que c’est le comportement normal ! dans une relation
has_one/belongs_to (tout comme dans une relation
has_many/belongs_to), c’est seuelement la clé étrangère qui est dans
l’entité ayant le “belongs_to” qui est manipulée.

une fois ton member créé, tu devrais toujours avoir accès à member.user (il
aura fait une recherche des user ayant le
bon member_id)

par contre si je transforme la relation Member => User en belongs_to, cela
fonctionne bien !!

c’est logique… mais inutile !

gUI


Pour la santé de votre ordinateur, préférez les logiciels libres !

Guillaume B. : (05 61) 19 40 65 / bureau 602N

Guillaume B. wrote:

le problème c’est qu’à la création du membre, le member_id au niveau de
users est bien renseigné mais pas le user_id dans members…

il me semble que c’est le comportement normal ! dans une relation has_one/belongs_to (tout comme dans une relation
has_many/belongs_to), c’est seuelement la clé étrangère qui est dans l’entité ayant le “belongs_to” qui est manipulée.

je ne vois pas trop pourquoi, mais si tu le dis :slight_smile:

une fois ton member créé, tu devrais toujours avoir accès à member.user (il aura fait une recherche des user ayant le
bon member_id)

oui mais là ce n’est pas le cas :confused:

par contre si je transforme la relation Member => User en belongs_to, cela
fonctionne bien !!

c’est logique… mais inutile !

je ne vois pas pourquoi c’est inutile… depuis mon member, j’ai aussi
besoin de récupérer le user.

merci pour tes réponses,

julien

def validate
if zip_code && ! ( zip_code.to_s =~ /^\d+( \d+)?$/ )
errors.add(:zip_code, “is invalid”)
end
end

tout est accepté !

j’avoue être un peu déconcerté. si vous pouvez m’éclairer, j’en serais
ravi :slight_smile:
en fait si je passe mon champ en :string (plutôt que :int) dans la
définition de ma table, tout fonctionne…

Le Ven 22 décembre 2006 11:44, Guillaume B. a écrit :

il me semble que c’est le comportement normal ! dans une relation
has_one/belongs_to (tout comme dans une relation
has_many/belongs_to), c’est seuelement la clé étrangère qui est dans
l’entité ayant le “belongs_to” qui est manipulée.

Si je ne me trompe pas, ça a été corrigé/étendu dans la 1.2 et désormais
on peut ajouter la relation par les deux bouts.
Il faut dire qu’il était plutot étrange de demander au développeur de
traiter différement la relation suivant le sens et de se poser la question
sur l’implémentation des clés dans le modèle relationnel pour pouvoir
utiliser les objets.


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

Eric D. wrote:

Il faut dire qu’il était plutot étrange de demander au développeur de
traiter différement la relation suivant le sens et de se poser la question
sur l’implémentation des clés dans le modèle relationnel pour pouvoir
utiliser les objets.

ça a dû être corrigé récemment car j’utilise la révision 5736 du trunk
(edge actuellement), et on en est à la 5772. ceci dit je n’ai pas vu de
message à ce sujet dans les commit depuis…

merci pour ta réponse.

je ne vois pas pourquoi c’est inutile… depuis mon member, j’ai aussi
besoin de récupérer le user.

et un member.user ne fonctionne pas ???

gUI


Pour la santé de votre ordinateur, préférez les logiciels libres !

Guillaume B. : (05 61) 19 40 65 / bureau 602N

Le Ven 22 décembre 2006 13:40, Julien B. a écrit :

ça a dû être corrigé récemment car j’utilise la révision 5736 du trunk
(edge actuellement), et on en est à la 5772. ceci dit je n’ai pas vu de
message à ce sujet dans les commit depuis…

Hum … ça doit être plus vieux que ça. Ton problème doit être autre chose
alors, désolé pour la fausse réponse.
(inversement c’est peut être aussi simplement quelque chose qui est cassé
temporairement dans les versions en développement)


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

Julien:

je ne vois pas trop pourquoi, mais si tu le dis :slight_smile:
Guillaume a raison.

je ne vois pas pourquoi c’est inutile… depuis mon member, j’ai aussi
besoin de récupérer le user.

Tu as Member has_one :user et User belongs_to :member.

Soit des tables comme ça :
members(id, …)
users(id, member_id, …)

Supposons que l’user 5 est associé au member 3.

Comment on ferait en SQL ? en gros, on ferait ça :

  • connaissant l’user 5, je veux le member 3 :
    (j’ai accès au champ member_id, je sais qu’il vaut 3)

SELECT * FROM members WHERE members.id= 3

  • connaissant le member 3, je veux l’user 5 :

SELECT * FROM users WHERE users.member_id = 3
(je passe le LIMIT 1)

A aucun moment, on n’a besoin d’une colonne user_id dans la
table members.

Une seule clé étrangère suffit (pareil pour has_many/belongs_to)

РJean-Fran̤ois.

Hum … ça doit être plus vieux que ça.

je viens de tester avec Rails 1.1.6 (utilisé par InstantRails pour
Windows), et la relation marche parfaitement dans les
2 sens (alors que j’ai simplement déclaré un suel ‘has_one’ et un seul
‘belongs_to’).

user.membre.user.membre.user…

tu pourrais dire en quoi ca ne marche pas ? quelle est l’erreur ?

gUI

Pour la santé de votre ordinateur, préférez les logiciels libres !

Guillaume B. : (05 61) 19 40 65 / bureau 602N

Le Ven 22 décembre 2006 15:23, Guillaume B. a écrit :

Hum … ça doit être plus vieux que ça.

je viens de tester avec Rails 1.1.6 (utilisé par InstantRails pour
Windows), et la relation marche parfaitement dans les
2 sens (alors que j’ai simplement déclaré un suel ‘has_one’ et un seul
‘belongs_to’).

user.membre.user.membre.user…

Ca c’est normal. Une relation existante est lisible dans les deux sens.
Ce
dont on parlait c’est surtout de la création de la relation.

Récapitulons. Voici l’état de ma connaissance (donc sujet à erreurs) :

En considérant une relation entre HO et BT avec les codes suivants :
HO :has_one BT
BT :belongs_to HO

  • Dans Rails < 1.2.0

    • on peut parcourir (lire) une relation dans les deux sens : ho.bt
      et
      bt.ho)
    • on ne peut créer une relation que via bt.ho=xx et pas via ho.bt=xx.
      On garde en tête l’implémentation SQL où la table modifiée est celle
      de BT.
  • A partir de Rails 1.2.0

    • on peut toujours parcourir les relations dans les deux sens
    • on peut aussi créer les relations dans les deux sens

Désolé, je n’ai pas le temps ni le courage de vérifier dans le code
source, mais si j’ai raison ça doit se trouver dans les changelog
d’ActiveRecord.


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

Tu as Member has_one :user et User belongs_to :member.

Soit des tables comme ça :
members(id, …)
users(id, member_id, …)
c’est là où je me suis planté : j’avais un champ user_id dans member…

merci beaucoup :slight_smile: