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!
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
.
comment Rails sait-il que
user_id
est une clé étrangère référençantuser
?
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
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.
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`