这是这个问题的完整答案,以防访问这个问题的人是 Ruby on Rails 的新手并且很难将所有东西放在一起(就像我第一次研究这个问题时一样)。
解决方案的某些部分发生在您的迁移中,一些发生在您的模型中:
迁移
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
在这里,您指定此表中有两列将被称为 :sender 和 :recipient ,它们包含对另一个表的引用。Rails 实际上会为您创建名为 'sender_id' 和 'recipient_id' 的列。在我们的例子中,它们将引用用户表中的每个行,但我们在模型中指定,而不是在迁移中。
楷模
class PrivateMessage < ActiveRecord::Base
belongs_to :sender, :class_name => 'User'
belongs_to :recipient, :class_name => 'User'
end
在这里,您将在 PrivateMessage 模型上创建一个名为 :sender 的属性,然后指定该属性与 User 类相关。Rails 看到“belongs_to :sender”,将在您的数据库中查找我们在上面定义的名为“sender_id”的列,并使用它来存储外键。然后你为收件人做同样的事情。
这将允许您通过 PrivateMessage 模型的实例访问您的发件人和收件人,这两个用户模型的实例,如下所示:
@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 的属性,指定此属性与 PrivateMessage 模型相关,并且将其与此属性相关的 PrivateMessage 模型上的外键称为“sender_id”。然后你对收到的私人消息做同样的事情。
这使您可以通过执行以下操作来获取所有用户发送或接收的私人消息:
@user.sent_private_messages
@user.received_private_messages
执行其中任何一个都将返回 PrivateMessage 模型的实例数组。
……