2011-03-11 4 views
2

Espérons que je ne suis pas flambé pour celui-ci trop mauvais - j'ai essayé mon très difficile de trouver une réponse en vain.Déclarer des associations dans Ruby on Rails

Je me demandais si quelqu'un pouvait me aider à comprendre comment déclarer correctement les associations en Ruby on Rails (3). À l'heure actuelle, j'ai 3 modèles:

#room.rb 
class Room < ActiveRecord::Base 
    has_many :check_ins 
end 

#check_in.rb 
class CheckIn < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :room 
end 

#user.rb 
class User < ActiveRecord::Base 
    has_one :check_in 
end 

Jusqu'à présent, je n'ai pas fait des migrations pour ajouter des colonnes foreign_key à une de mes tables (ne Rails font pour vous?).

Je suis confus au sujet de pourquoi la commande CheckIn.first.user renvoie nil alors que la commande User.first.check_in renvoie SQLite3::SQLException: no such column. La même chose se produit par rapport à CheckIn.first.room et Room.first.check_ins, respectivement. Que dois-je faire pour que User.first.check_in renvoie l'objet CheckIn associé au premier utilisateur et Room.first.check_ins renvoie l'ensemble de CheckIns associé au premier Room?

Toute aide serait grandement appréciée.

Charlie

Répondre

4

Comment avez-vous généré ces modèles à l'origine? Avez-vous créé les fichiers du modèle, ou avez-vous utilisé le générateur de modèles de rails (qui génère également une migration pour vous)?

#room.rb 
class Room < ActiveRecord::Base 
    has_many :check_ins 
end 

#check_in.rb 
class CheckIn < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :room 
end 

#user.rb 
class User < ActiveRecord::Base 
    has_one :check_in 
    has_one :room, :through => :check_in 
end 

Dans db/migrations/34612525162_something_something.rb Vous devez vous assurer que vous avez des migrations qui définissent ces tables pour vous. La meilleure façon pour vous de le faire serait d'exécuter cette commande dans une console, modifier les commandes à utiliser les champs que vous voulez, les champs * _id sont nécessaires pour vos associations au travail:

rails generate model user name:string email:string otherfield:integer 
rails generate model check_in user_id:integer room_id:integer 
rails generate model room number:integer 

Notez que ces va également générer des fichiers modèles pour vous, puisque vous avez déjà ces 3 fichiers modèles, il vous demandera si vous voulez les écraser, ou ignorer les fichiers. Vous pouvez les ignorer et ça devrait aller. Si vous aviez déjà les migrations pour une partie des données contenues dans ces modèles, vous pouvez simplement ajouter les champs user_id et ROOM_ID au modèle de contrôle-entrée en exécutant ce générateur au lieu:

rails generate migration AddIdsToCheckIn user_id:integer room_id:integer 

Pour rails 2.3.x remplacer rails generate avec script/generate. Ensuite, vous pouvez inspecter votre (vos) migration (s) en ouvrant les fichiers en db/migrate.rb et en les modifiant si nécessaire.Enfin, exécutez les migrations:

rake db:migrate 

Et cela devrait marcher pour vous. Notez que j'ai ajouté une relation has_one, :through => à l'utilisateur - c'est ainsi que vous pouvez faire @user.room sans avoir à faire 3 chaînes:

+0

Grande réponse - très descriptif! L'idée principale qui me manquait était que j'avais besoin d'ajouter les colonnes user_id et room_id à check_in via une migration. En outre, merci pour le conseil sur l'idée ': through' - cela vous sera utile! – candrews

0

Vous devez ajouter les migrations vous (ou si vous ne vivez pas, vous pouvez modifier une migration existante). Fondamentalement, vous devez donner au côté belongs_to de la relation une clé étrangère.

+0

Cela a très bien fonctionné! La commande que j'ai fini par utiliser pour générer une telle migration (pour tous ceux qui pourraient trouver cela dans le futur) était 'rails g migration add_room_id_to_check_ins room_id: integer' (évidemment suivi d'un' rake db: migrate'). Merci pour l'aide! – candrews

+0

@candrews apparemment je tape trop lent: p – nzifnab

+0

haha, eh bien, ils étaient tous deux de bonnes réponses, l'un était juste un peu plus rapide. J'étais un peu déchiré = p – candrews

0

Il n'y a absolument aucune raison de faire incendier ne vous inquiétez pas :) Il semble ici que vous essayez de faire une association un à plusieurs, mais vous êtes en train de faire un grand nombre à beaucoup un.

Si un utilisateur a un enregistrement, cela signifie qu'il/elle a une pièce. , Vous pourriez avoir ceci:

utilisateur chambre has_one chambre appartient à l'utilisateur

et chambre dispose d'une user_id.

Espérons que ça aide :)

+0

Haha, ben merci pour la confiance boost = p J'aurais dû être plus un peu moins étroit dans ma question - il y a d'autres attributs à CheckIn qui font en sorte qu'il soit logique que CheckIn soit son propre modèle. La réponse de Kevin m'a orienté dans la bonne direction, cependant, je l'ai compris. Je vous remercie! – candrews

+0

vous êtes les bienvenus je suis content que vous avez tout ensemble :) – Spyros