Question

Est-il possible de mettre en place une double relation dans les modèles activerecord via la commande generate scaffold?

Par exemple, si j'avais un modèle User et un modèle PrivateMessage, la table h aurait besoin de garder une trace des deux l'sender et recipient.

Il est évident que, pour une seule relation que je voudrais juste faire ceci:

ruby script/generate scaffold pm title:string content:string user:references

Y at-il une manière similaire à mettre en place deux relations?

En outre, il est de toute façon de mettre en place des alias pour les relations?

Ainsi, plutôt que de dire:

@message.user

Vous pouvez utiliser quelque chose comme:

@message.sender ou @message.recipient

Tout conseil serait grandement apprécié.

Merci.

Était-ce utile?

La solution

Ajoutez ceci à votre modèle

has_one :sender, :class_name => "User"
has_one :recipient, :class_name => "User"

Et vous pouvez appeler @message.sender et @message.recipient et à la fois référence au modèle de l'utilisateur.

Au lieu de user:references dans votre commande, vous aurez besoin de générer sender:references et recipient:references

Autres conseils

Voici une réponse complète à cette question, dans le cas de personnes qui visitent cette question sont nouveaux à Ruby on Rails et d'avoir du mal à tout mettre ensemble (comme je l'étais quand je regardais dans ce sujet).

Certaines parties de la solution ont lieu dans votre et quelques-uns dans les migrations de vos modèles:

Migrations

class CreatePrivateMessages < ActiveRecord::Migration
  def change
    create_table :private_messages do |t|
      t.references :sender
      t.references :recipient
    end
    # Rails 5+ only: add foreign keys
    add_foreign_key :private_messages, :users, column: :sender_id, primary_key: :id
    add_foreign_key :private_messages, :users, column: :recipient_id, primary_key: :id
  end
end

Ici, vous indiquez qu'il ya deux colonnes dans ce tableau qui sera nommé: expéditeur et: destinataire et qui contiennent des références à une autre table. Rails en fait créer des colonnes appelées « sender_id » et « recipient_id » pour vous. Dans notre cas, ils seront chacun des lignes de référence dans la table des utilisateurs, mais nous précisons que dans les modèles, pas dans les migrations.

Modèles

class PrivateMessage < ActiveRecord::Base
  belongs_to :sender, :class_name => 'User'
  belongs_to :recipient, :class_name => 'User'
end

Ici, vous créez une propriété sur le modèle PrivateMessage nommé: l'expéditeur, puis en spécifiant que cette propriété est liée à la classe utilisateur. Rails, voir le « belongs_to: l'expéditeur », va chercher une colonne dans votre base de données appelée « sender_id », que nous avons défini ci-dessus, et l'utiliser pour stocker la clé étrangère. Ensuite, vous faites exactement la même chose pour le destinataire.

Cela vous permettra d'accéder à votre expéditeur et le destinataire, les deux instances du modèle de l'utilisateur, par une instance du modèle PrivateMessage, comme ceci:

@private_message.sender.name
@private_message.recipient.email

Voici votre modèle utilisateur:

class User < ActiveRecord::Base
  has_many :sent_private_messages, :class_name => 'PrivateMessage', :foreign_key => 'sender_id'
  has_many :received_private_messages, :class_name => 'PrivateMessage', :foreign_key => 'recipient_id'
end

Ici, vous créez une propriété sur le modèle utilisateur nommé: sent_private_messages, en précisant que cette propriété est liée au modèle PrivateMessage, et que la clé étrangère sur le modèle PrivateMessage auquel il se rapporte à cette propriété est appelée « sender_id ». Ensuite, vous faites la même chose pour les messages privés reçus.

Cela vous permet d'obtenir tous les utilisateurs d'un envoyé ou reçu des messages privés en faisant quelque chose comme ceci:

@user.sent_private_messages
@user.received_private_messages

Faire ou l'autre de ceux-ci reviendront un tableau d'instances du modèle PrivateMessage.

....

Salut à tous d'avoir les deux à côte faites comme ci-dessous dans vos deux modèles:

class Message < ActiveRecord::Base

 belongs_to     :sender,
                :class_name => "User",
                :foreign_key  => "sender_id"

 belongs_to     :recipient,
                :class_name => "User",
                :foreign_key  => "recipient_id" 
end

class User < ActiveRecord::Base

  has_many      :sent, 
                :class_name => "Message",
                :foreign_key  => "sent_id"

  has_many      :received, 
                :class_name => "Message", 
                :foreign_key  => "received_id"
end

J'espère que cela vous aide ...

Les réponses ci-dessus, tout en excellent, ne créent pas de contraintes de clé étrangère dans la base de données, au lieu que de créer des index et des colonnes bigint. Pour faire en sorte que la contrainte de clé étrangère est appliquée, ajoutez ce qui suit à votre migration:

class CreatePrivateMessages < ActiveRecord::Migration[5.1]
    def change
        create_table :private_messages do |t|
          t.references :sender
          t.references :recipient
        end

        add_foreign_key :private_messages, :users, column: :sender_id, primary_key: :id
        add_foreign_key :private_messages, :users, column: :recipient_id, primary_key: :id
    end
end

Cela permettra d'assurer que les indices sont créées sur le sender_id et recipient_id ainsi que les contraintes de clé étrangère dans la base de données que vous utilisez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top