Je pense que vous avez votre belongs_to
/has_many
un peu en arrière.
belongs_to et has_many
Pour votre exemple,
class Tp < ActiveRecord::Base
has_many :dogs
has_many :cats
has_many :stars
end
Tp
n'ont pas dog_id
, cat_id
ou star_id
dans sa ligne de base de données. Lorsque vous définissez belongs_to
dans les autres modèles,
class Dog < ActiveRecord::Base
belongs_to :tp
end
class Cat < ActiveRecord::Base
belongs_to :tp
end
class Star < ActiveRecord::Base
belongs_to :tp
end
Vous devez ajouter un tp_id
à chaque modèle (tableau dogs
, table cats
et stars
tableau).
Puis, appelant
tp = Tp.find(123)
Tp
avec Constate id
égal à 123
SELECT * FROM tps WHERE id = 123;
Et appeler
cats = tp.cats
dogs = tp.dogs
stars = tp.stars
recherche tous les Cat
, Dog
et Star
insta nces avec tp_id
égal à 123
SELECT * FROM cats WHERE tp_id = 123;
SELECT * FROM dogs WHERE tp_id = 123;
SELECT * FROM stars WHERE tp_id = 123;
Si vous avez besoin de vos Cat
cas d'appartenir à de nombreux cas Tp
et Tp
cas d'avoir de nombreux Cat
cas, alors vous devriez regarder Rails pour has_and_belongs_to_many ou has_many :through.
has_and_belongs_to_many
une relation has_and_belongs_to
nécessiterait de nouvelles tables cats_tps
, dogs_tps
et stars_tps
. Ces tables auraient un schéma de
cats_tps
cat_id
tp_id
dogs_tps
dog_id
tp_id
stars_tps
star_id
tp_id
Puis dans vos modèles
class Tp < ActiveRecord::Base
has_and_belongs_to_many :dogs
has_and_belongs_to_many :cats
has_and_belongs_to_many :stars
end
class Dog < ActiveRecord::Base
has_and_belongs_to_many :tps
end
class Cat < ActiveRecord::Base
has_and_belongs_to_many :tps
end
class Star < ActiveRecord::Base
has_and_belongs_to_many :tps
end
Maintenant, la course
tp = Tp.find(123)
cats = tp.cats
Génère le SQL
SELECT "cats".* FROM "cats" INNER JOIN "cats_tps" ON "cats"."id" = "cats_tps"."cat_id" WHERE "cats_tps"."tp_id" = 123;
Quelle est essentialy la requête (Obtenez-moi une liste o f tous les cat_ids qui appartiennent à Tp 123) et puis (obtenez-moi tous les chats qui correspondent à ces identifiants de chat).
Génération du tableau cats_tps
jointure peut se faire avec une migration comme
class CreateCatsTps < ActiveRecord::Migration
def change
create_table :cats_tps, :id => false do |t|
t.belongs_to :cat
t.belongs_to :tp
end
end
end
Cela fonctionne très bien pour les jointures simples, mais vous voudrez peut-être regarder dans has_many :through
. C'est parce que la table cats_tps
ne détient aucune information sur quand ou pourquoi ce Cat
appartient à un Tp
ou ce Tp
appartient au Cat
. De même, si vous ajoutez des modèles Bird
, Horse
, Frog
et Snake
, vous devrez créer les tableaux birds_tps
, horses_tps
, frogs_tps
et snakes_tps
. Yuck.
has_many: par
Pour créer une relation has_many :through
, vous créez un nouveau modèle qui est logique sémantiquement qui relie un Tp
à un Cat
. Par exemple, disons qu'un Tp
promène des chats. Vous pouvez créer un modèle Walk
qui relie un Cat
à un Tp
.
class Walk < ActiveRecord::Base
belongs_to :cat
belongs_to :tp
attr_accessible :price, :duration, :interval # these attributes describe the Walk relationship
end
class Cat < ActiveRecord::Base
has_many :walks
has_many :tps, :through => :walks
end
class Tp < ActiveRecord::Base
has_many :walks
has_many :cats, :through => :walks
end
Maintenant, la relation est semblable à un has_and_belongs_to_many
, mais vous pouvez inclure des métadonnées sur la relation de marche. De plus, disons qu'un Tp
promène aussi des chiens. Vous pouvez convertir le belongs_to :cat
en une relation polymorphe belongs_to :animal
afin qu'un Tp
puisse promener un chat, un chien, une souris, un lapin, un cheval, ... vous l'appelez.
class Walk < ActiveRecord::Base
belongs_to :animal, :polymorphic => true
belongs_to :tp
attr_accessible :price, :duration, :interval # these attributes describe the Walk relationship
end
class Cat < ActiveRecord::Base
has_many :walks, :as => :animal
has_many :tps, :through => :walks
end
class Dog < ActiveRecord::Base
has_many :walks, :as => :animal
has_many :tps, :through => :walks
end
class Tp < ActiveRecord::Base
has_many :walks
has_many :cats, :through => :walks, :source => :animal, :source_type => 'Cat'
has_many :dogs, :through => :walks, :source => :animal, :source_type => 'Dog'
end
Cette relation est créée avec une migration comme
class CreateWalks < ActiveRecord::Migration
def change
create_table :walks do |t|
t.belongs_to :animal, :polymorphic => true
t.belongs_to :tp
end
end
end
Avez-vous lu http://guides.rubyonrails.org/association_basics.html? –
@AlexTeut oui j'ai – jamesdlivesinatree