Ruby on rails – 引用同一模型两次?

是否有可能通过generate scaffold命令在activerecord模型中build立双重关系?

例如,如果我有一个User模型和一个PrivateMessage模型,pm表将需要跟踪senderrecipient

显然,对于一个单一的关系,我只是这样做:

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

有没有类似的方式来build立两个关系?

另外,有没有build立关系的别名?

所以而不是说:

 @message.user 

你可以使用像这样的东西:

@message.sender@message.recipient

任何build议将不胜感激。

谢谢。

将此添加到您的模型

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

你可以调用@message.sender@message.recipient ,同时引用User模型。

而不是user:references您的生成命令中的user:references ,你需要sender:referencesrecipient:references

这里是对这个问题的完整答案,以防万一访问这个问题的人对Ruby on Rails不熟悉,而且把所有的东西都放在一起(就像我第一次看到这个时)。

解决scheme的一些部分发生在您的迁移中,一些发生在您的模型中:

迁移

 class CreatePrivateMessages < ActiveRecord::Migration create_table :private_messages do |t| def up 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 

这里你指定在这个表中有两列将被称为:发件人和:收件人,并持有对另一个表的引用。 实际上,Rails会为你创build一个名为“sender_id”和“recipient_id”的列。 在我们的例子中,它们将引用Users表中的行,但是我们在模型中指定,而不是在迁移中。

楷模

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

在这里,您将在名为sender的PrivateMessage模型上创build一个属性,然后指定该属性与User类相关。 看到“belongs_to:sender”的Rails将在你的数据库中寻找一个名为“sender_id”的列,并且使用它来存储外键。 然后你对收件人完全一样。

这将允许您通过一个PrivateMessage模型的实例来访问您的发件人和收件人,这两个User模型的实例都是这样的:

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

这是您的用户模型:

 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 

在这里,您正在名为:sent_private_messages的用户模型上创build一个属性,指定该属性与PrivateMessage模型相关,并且将PrivateMessage模型中与该属性相关的外键称为“sender_id”。 那么你对收到的私人信息做同样的事情。

这可以让你通过做这样的事情得到所有的用户发送或接收私人信息:

 @user.sent_private_messages @user.received_private_messages 

做这些将会返回一个PrivateMessage模型的实例的数组。

….

嗨那里有双方关系做你的两个模型波纹pipe:

 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 

我希望这可以帮助你…

上面的答案虽然很好,但不会在数据库中创build外键约束,而只能创build索引和bigint列。 为确保强制实施外键约束,请将以下内容添加到您的迁移中:

 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 

这将确保在sender_idrecipient_id上创build索引以及在您使用的数据库中的外键约束。