web-dev-qa-db-fra.com

générer un modèle en utilisant utilisateur: références vs utilisateur_id: entier

Je suis confus sur la façon de générer un modèle qui appartient à un autre modèle. Mon livre utilise cette syntaxe pour associer Micropost à Utilisateur:

Rails generate model Micropost user_id:integer

mais http://guides.rubyonrails.org/ dit de le faire comme ceci:

Rails generate model Micropost user:references

Les migrations générées par ces 2 sont différentes. Par ailleurs, comment Rails sait-il que user_id est une clé étrangère référençant user? Merci!

169
stackOverlord

Les deux généreront les mêmes colonnes lors de l'exécution de la migration. Dans la console Rails, vous pouvez voir que c'est le cas:

:001 > Micropost
=> Micropost(id: integer, user_id: integer, created_at: datetime, updated_at: datetime)

La deuxième commande ajoute une relation belongs_to :user dans votre modèle Micropost, contrairement à la première. Lorsque cette relation est spécifiée, ActiveRecord supposera que la clé étrangère est conservée dans la colonne user_id et utilisera un modèle nommé User pour instancier l'utilisateur spécifique.

La deuxième commande ajoute également un index sur la nouvelle colonne user_id.

186
Jon M.

comment Rails sait-il que user_id est une clé étrangère référençant user?

Rails lui-même ne sait pas que user_id est une clé étrangère référençant user. Dans la première commande Rails generate model Micropost user_id:integer, il ajoute uniquement une colonne user_id mais Rails ne connaît pas l'utilisation de la colonne. Vous devez insérer manuellement la ligne dans le modèle Micropost

class Micropost < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :microposts
end

les mots-clés belongs_to et has_many déterminent la relation entre ces modèles et déclarent user_id en tant que clé étrangère de User modèle.

La dernière commande Rails generate model Micropost user:references ajoute la ligne belongs_to :user dans le modèle Micropost et déclare par la présente la clé étrangère.

FYI
La déclaration des clés étrangères à l'aide de l'ancienne méthode permet uniquement au Rails de connaître la relation entre les modèles/tables. La base de données est inconnue sur la relation. Par conséquent, lorsque vous générez les diagrammes EER à l'aide d'un logiciel tel que MySql Workbench, vous constatez qu'il n'y a pas de fil de relation tracé entre les modèles. Comme dans la photo suivante enter image description here

Cependant, si vous utilisez la méthode la plus récente, votre fichier de migration se présente comme suit:

def change
    create_table :microposts do |t|
      t.references :user, index: true

      t.timestamps null: false
    end
    add_foreign_key :microposts, :users

Maintenant, la clé étrangère est définie au niveau de la base de données. et vous pouvez générer les diagrammes EER appropriés. enter image description here

42
illusionist

Pour les premiers, convention sur la configuration. Rails défaut lorsque vous référencez une autre table avec

 belongs_to :something

est de chercher something_id.

references, ou belongs_to est en fait une manière plus récente d'écrire l'ancien avec quelques bizarreries.

Il est important de se rappeler que cela ne créera pas de clé étrangère pour vous. Pour ce faire, vous devez le configurer explicitement en utilisant:

t.references :something, foreign_key: true
t.belongs_to :something_else, foreign_key: true

ou (notez le pluriel):

add_foreign_key :table_name, :somethings
add_foreign_key :table_name, :something_elses`
15
Krule