web-dev-qa-db-fra.com

has_many, appartient à la relation dans la migration d'enregistrement actif Rails 4

J'ai créé un modèle User et plus tard un modèle Task. Je n'ai mentionné aucune relation entre eux lors de la création.

Je comprends que Userhas_manyTasks et un Taskbelongs_toUser. Je dois établir cette relation entre eux par la migration.

Ma question est la suivante: quelle serait la commande de génération de migration pour établir cette relation?

Toute aide serait très appréciée.

59
Hasan Iqbal

Vous pouvez appeler:

Rails g model task user:references

qui générera un user_id colonne dans la table tasks et modifiera la colonne task.rb modèle pour ajouter un belongs_to :user relation. S'il vous plaît noter que vous devez mettre manuellement le has_many :tasks ou has_one :task relation avec le user.rb modèle.

Si le modèle est déjà généré, vous pouvez créer une migration avec les éléments suivants:

Rails g migration AddUserToTask user:belongs_to

qui générera:

class AddUserToTask < ActiveRecord::Migration
  def change
    add_reference :tasks, :user, index: true
  end
end

la seule différence avec cette approche est que le belongs_to :user _ relation dans le task.rb modèle ne sera pas créé automatiquement, vous devez donc le créer pour vous-même.

73
Alter Lagos

Pour répondre à la question "Quelle serait la commande de génération de migration pour établir cette relation?" (Comment ajouter une migration pour les modèles existants avec une relation comme User has_many Tasks & Task belongs_to User)

Le moyen le plus facile pour moi de me souvenir est le suivant:

>Rails g migration AddUserToTask user:belongs_to

ou

>Rails g migration AddUserToTask user:references

:belongs_to _ est juste un alias de :references, soit va faire la même chose.

En procédant ainsi, la commande déduira le nom de la table à partir du nom de la migration, configurera une méthode de changement qui ajoutera la colonne pour la relation et la configurera pour être indexée:

class AddUserToTask < ActiveRecord::Migration
  def change
    add_reference :tasks, :user, index: true
  end
end

Après avoir généré cela, vous:

>rake db:migrate

Enfin, vous devez encore ajouter les relations habituelles à vos modèles, comme indiqué dans les autres réponses, mais je pense que c'est la bonne réponse à votre question.

27
chad_

Comment cela devrait-il être fait lors de la création de la migration:

Rails g scaffold child parent:references


Que faire si vous avez oublié le parent:references bit:

Si vous n'avez pas vraiment beaucoup défini dans le modèle/db sur l'enfant. Votre meilleur pari pourrait bien être de courir Rails destroy scaffold child, puis exécutez Rails g scaffold child parent:references par-dessus. Assurez-vous d'ajouter la ligne drop_table :children if table_exists? :children avant de créer la table dans le fichier qui crée la nouvelle table. (Ainsi, si quelqu'un récupère votre code, il peut simplement exécuter les migrations et le faire.) Cependant, il semble plus probable que vous disposiez déjà de données que vous ne voulez pas perdre dans le modèle enfant.


Dans ce cas:

Rails g migration add_parent_refs_to_child

## XXXXXXXXXXXXXX_add_parent_refs_to_child.rb
class AddParentRefsToChild < ActiveRecord::Migration
  def change
    add_reference :child, :parent, index: true
  end
end

Voir add_reference pour plus de détails.

De plus, n'oubliez pas de vous assurer que le modèle parent has_[one | many] :children, et que le modèle enfant belongs_to :parent.


Comment ne pas le faire:

Vous pouvez être tenté d'entrer et d'ajouter manuellement le parent_id, ce qui n'est certainement pas la meilleure solution car ce n'est pas la méthode conventionnelle pour ajouter des clés étrangères et ne se prête pas très bien à la maintenance ou à la lisibilité. . Convention sur la configuration!

Le Ruby on Rails guide d'association contient également des informations plus utiles sur le sujet.

16
0112

Aucune commande de migration spéciale ne serait utilisée.

Dans votre modèle d'utilisateur, vous mettrez

class User < ActiveRecord::Base
  has_many :tasks
end

class Task < ActiveRecord::Base
  belongs_to :user
end

Dans le fichier de migration correspondant aux tâches, vous avez ajouté le champ suivant: user_id

Jetez un oeil à ceci guide

5
Althaf Hameez

La relation dans Rails est prise en charge par le modèle et non par Rails.

Il vous suffit donc de définir cette relation dans votre modèle:

class User < ActiveRecord::Base
  has_many :tasks
end

class Task < ActiveRecord::Base
  belongs_to :user
end

Et assurez-vous simplement qu'un champ user_id Est présent dans la migration pour créer la table "tâches".

4
Amitkumar Jha

La migration ajoutera l'ID de l'utilisateur à la table des tâches pour qu'il se connaisse

Rails g migration AddUserIdToTask user_id:integer

puis

rake db:migrate

Et après la mise à jour de vos contrôleurs et de vos vues, les tâches ne peuvent pas être créées seules mais doivent correspondre à un utilisateur.

4
Connor Leech