2010-12-31 5 views
0

Je suis un programmeur débutant, je fais des scripts shell depuis des années mais j'ai récemment entrepris une programmation OOP en utilisant Ruby et je crée une application Rails.Usng Rails Relations ActiveRecord

J'ai du mal à comprendre comment utiliser mes relations de modèle définies.

J'ai essayé de faire une recherche sur Google, mais tout ce que je peux trouver est essentiellement des feuilles de triche pour ce que has_many, belongs_to, etc. Ce truc est facile à définir & comprendre, d'autant plus que j'ai beaucoup travaillé directement avec SQL.

Ce que je ne comprends pas, c'est comment utiliser ces relations définies.

Dans mon cas, j'ai 3 modèles: Emplacements hôtes services

Relations (code non réel, juste pour le raccourcir):

Services 
    belongs_to :hosts 

Hosts 
    has_many :services 
    belongs_to :locations 

Locations 
    has_many :hosts 

Dans ce cas, je veux être en mesure de afficher une colonne à partir des emplacements tout en travaillant avec les services. En SQL, il s'agit d'une jointure simple, mais je veux le faire de la manière Rails/Ruby, et aussi ne pas utiliser SQL dans mon code ou redéfinir mes jointures.

Répondre

0

Vous pouvez définir un has_many via sur Emplacements.

Locations 
    has_many :hosts 
    has_many :services, :through => :hosts 

Hosts 
    belongs_to :location 
    has_many :services 

Services 
    belongs_to :host 
    has_one :location, :through => :host #This relationship is optional 

Ensuite, vous pouvez accéder aux services par:

Location.first.services 

Cela va générer cette requête:

SELECT "services".* FROM "services" INNER JOIN "hosts" ON "services".host_id = "hosts".id WHERE (("hosts".location_id = 1)) 

... qui recueillera tous les services pour un endroit donné .

EDIT: Je me rends compte que vous voulez la relation de l'autre extrémité. Pour ce faire, vous pouvez accéder à l'emplacement à partir d'un service en effectuant service.host.location car chaque service appartient à un hôte et chaque hôte appartient à un emplacement. Vous pouvez également ajouter la relation facultative ci-dessus, donc vous pouvez simplement taper service.location.column_name.

+0

En outre, Seth a raison à propos des relations qui doivent être correctement pluralisées. De plus, votre requête de localisation sera probablement différente de «première», mais c'est une bonne illustration de la façon dont elle sera réalisée. –

+0

Has_many à travers ne fonctionnera pas parce que la table de jointure n'appartient pas à chaque côté propriétaire ... – sethvargo

+0

Pas vrai.Ça marche. Il génère cette requête: SELECT "services". * FROM "services" INNER JOIN "hosts" ON "services" .host_id = "hosts" .id OERE (("hosts" .location_id = 1)) –

0

Pour ce que je sais que vous devez vous habituer à utiliser noms singuliers pour vos modèles, donc:

 Service 
     belongs_to :host 

    Host 
     has_many :services 
     belongs_to :location 

    Location 
     has_many :hosts 

Notez que maintenant les relations font réellement sens: A has_many maîtres d'hôtel, un service belongs_to une hôte et un emplacement has_many accueille

maintenant, essayez sur la console rails:

service = Service.create(:name => 'ServiceName')#assuming you only have that field and the host_id of course 
service.host# right after creation will return an empty array...so create a host 
host = Host.create(:name => 'HostName')#assuming you only have that field and the id of course 
#if both were saved to db 
host.services << service 
#or 
service.host << host #should work for you 

vous pouvez alors appeler

service.host.name   
service.host.id # or any other column you have there