Dans une application Rails que je suis en train de créer, j'ai un blocage. Je
ne sais pas trop si ce blocage est une limitation de mon esprit ou de rails.
Voici donc mon problème.
J'ai 3 tables :
- Acteurs
- Films
- Roles
Dans chacune d'elle, il y a un champs nom. Mais voilà, je voudrais lier ces 3
tables entre elle mais de façon unique. Ainsi en réfléchissant de manière
purement SQL, je voulais créer une table comme suit :
CREATE TABLE acteur_film_role {
id INTEGER,
acteur_id INTEGER,
film_id INTEGER,
role_id INTEGER
}
Mais avec Rails, impossible de voir comment le schématiser à part en créant
un nouvel objet model qui schématisera cette nouvelle table composé de
belongs_to et has_many Mais cela m'imposera de créer cette objet à
chaque fois pour faire une liaison. Car en effet, le
has_and_belongs_to_many, ne me permet
de faire la liaison avec une base intermédiaire que de deux champs, pas
trois.
En réfléchissant au problème, je n'ai pas non plus vu d'autre moyen conceptuel
pour faire cette liaison à part comme je l'ai fait précédemment. Ce nouveau
moyen pourrait peut-être me résoudre mon problème.
Je suis ouvert à toutes propositions.
Merci
--
Cyril Mougel
Bonjour,
Je ne vois pas l'interet conceptuel du ::through ..
Merci d'éclairer ma lanterne....
Le problème est que faire ce système implique qu'un rôle n'a qu'un
seul acteur et film. Hors, il se trouve qu'un acteur peux avoir
plusieurs rôle dans un film, qu'un film a plusieurs acteurs par rôle
et qu'un film plusieurs acteurs. Donc, j'ai pas le choix, cette
possibilité ne pourra pas être utilisé à mon avis.
>
> PS: J'ai répondu sur ton blog pour le probéme d'ipv6 ;)
Merci à toi, j'ai répondu
--
Cyril Mougel
On 26 mai, 12:22, "Cyril Mougel" <cyril.mou...@gmail.com> wrote:
> On 5/26/07, Bastien Quelen <bastien.que...@gmail.com> wrote:
>
>
>
>
>
> > Le 26/05/07, Cyril Mougel <cyril.mou...@gmail.com> a écrit :
Je ne suis vraiment pas fan des clé composite. De plus dans mon cas là
clé composite serait composé de 3 champs, ce qui est encore moins bien
:(
--
Cyril Mougel
Oui, mais il faut définir un rôle sur tel ou tel film. Je ne peux donc
pas faire de liaison directe sur une des trois tables.
--
Cyril Mougel
> CREATE TABLE acteur_film_role {
> id INTEGER,
> acteur_id INTEGER,
> film_id INTEGER,
> role_id INTEGER
> }
>
> Mais avec Rails, impossible de voir comment le schématiser à
> part en créant un nouvel objet model qui schématisera cette
> nouvelle table composé de
> belongs_to et has_many
Oui et c'est une bonne solution àmha.
class Acteur < AR::B
has_many :compositions
has_many :films, :through => :compositions
has_many :personnages, :through => :compositions
end
class Film < AR::B
has_many :compositions
has_many :acteurs, :through => :compositions
has_many :personnages, :through => :compositions
end
class Personnage < AR::B
has_many :compositions
has_many :acteurs, :through => :compositions
has_many :films, :through => :compositions
end
Et le "join model" :
class Composition < AR::B
belongs_to :acteur
belongs_to :film
belongs_to :personnage
validates_uniqueness_of :acteur_id, :scope => [ :film_id, :personnage_id ]
end
Pour avoir la liste des films d'un acteur : acteur.films.uniq
tous les personnages qu'il a joués : acteur.personnages.uniq
tous les acteurs qui ont joué James Bond : james_bond.acteurs.uniq
pour créer une composition :
Composition.create :acteur => acteur, :film => film, :personnage => personnage
ou
Composition.create :acteur_id => acteur_id, :film_id => film_id,
:personnage_id => personnage_id
ou sean_connery.compositions.create(:personnage => james_bond,
:film => docteur_no)
etc.
donc on peut manipuler dans tous les sens.
> Mais cela m'imposera de créer cette objet à
> chaque fois pour faire une liaison.
C'est pas la mer à boire.
> Car en effet, le has_and_belongs_to_many, ne me permet
> de faire la liaison avec une base intermédiaire que de deux
> champs, pas trois.
L'autre avantage est que tu peux rajouter des champs
supplémentaire à la table compositions, genre 'doublage_voix'
pour préciser le rôle (j'ai préféré le terme personnage,
mais tu fais comme tu veux) par exemple d'Eddy Murphy
dans Shrek.
-- Jean-François.
--
À la renverse.
Merci beaucoup Jean-François. Très bonne explication. Je comprend tout.
--
Cyril Mougel
On May 26, 3:58 pm, "Cyril Mougel" <cyril.mou...@gmail.com> wrote:
je trouve que vous vous compliquez la vie.
un role a 0,n acteurs.
un acteur a 0,n roles.
donc il faut 3 tables:
acteurs 0,n->joue<-0,n roles
un film a 0,n roles
un role a a un seul film
donc:
films 0,n->roles
un film a plusieurs acteurs
ceci est trouvable par nos associations définis ci dessus
films->roles->joues->acteurs
de meme pour un acteur a plusieurs films
acteurs->joue->roles->films
certains pourraient me repliquer que mon modele ne fonctionne pas avec
l'exemple suivant.
plusieurs films ont le des acteurs qui joue le role de james bond.
je reponds que le role de james bon n'est pas le meme dans casino
royal que dans docteur no.
plusieurs roles peuvent avoir le meme nom de personnage.
on peut donc eventuellement rajouter une table pour lever toute
ambiguité:
roles 0,1<->0,n personnages.
il faut noter que les associations de rails ont un sens bcp plus
larges que dans merise ou UML.
on peut tres bien definir une association entre 2 modeles non pas par
une clé etrangere mais par une requete SQL
à l'aide de l'option :finder_sql.
donc on peut creer une association entre films et acteurs à l'aide
d'une requete sql.
Dans ton exemple tu as tout à fait raison. Mais dans mon cas, le rôle
n'est pas le personnage jouer sur le film, mais le rôle de la personne
dans la réalisation du film. Ainsi une même personne peux donc être
Réalisateur et comédien sur le même film comme l'est par exemple
Sophie Marceaux dans son dernier film.
J'ai implémenté la méthode de Jean-Francois et Bastien, car c'était
lui le premier qui avait parler des through et ca marche
impeccablement. Encore merci.
--
Cyril Mougel