编写一个参考模型的迁移两次

时间:2011-10-24 18:49:20

标签: ruby-on-rails ruby ruby-on-rails-3

我有一个消息模型(Message),这个模型作为userTo和userFrom,所以两个引用User。我该如何编写迁移?我的用户模型是User。

谢谢

2 个答案:

答案 0 :(得分:8)

以下是对此问题的完整答案,以防人们访问此问题时很难将所有内容放在一起(就像我第一次看到这个时一样)。

答案的某些部分发生在您的迁移中,而某些部分发生在您的模型中:

迁移

class CreateMessages < ActiveRecord::Migration
  create_table :messages do |t|
    def up
      t.references :sender
      t.references :recipient
    end
  end
end

此处指定此表中有两列将被称为:sender和:recipient,它们包含对另一个表的引用。 Rails实际上会为您创建名为“sender_id”和“recipient_id”的列。在我们的例子中,他们将每个引用Users表中的行,但我们在模型中指定,而不是在迁移中。

模型

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

这里,您要在Message模型上创建一个名为:sender的属性,然后指定此属性将引用User类的实例。看到“belongs_to”的Rails将在数据库中查找名为“sender_id”的列,我们在上面定义了该列,并使用它来存储外键。那么你正在为收件人做同样的事情。

这将允许您通过Message模型的实例访问User模型的两个实例的Sender和Recipient,如下所示:

@message.sender.name
@message.recipient.email

以下是您的用户模型:

class User < ActiveRecord::Base
  has_many :sent_messages, :class_name => 'Message', :foreign_key => 'sender_id'
  has_many :received_messages, :class_name => 'Message', :foreign_key => 'recipient_id'
end

在这里,您要在名为:sent_messages的用户模型上创建一个属性,指定此属性与消息模型相关,并且Message模型上与此属性相关的外键称为“sender_id”。然后你对收到的消息做了同样的事情。

这允许您通过执行以下操作来获取所有用户发送或接收的消息:

@user.sent_messages
@user.received_messages

执行其中任何一项操作都将返回Message模型的实例数组。

答案 1 :(得分:3)

在迁移中,为每种用户创建两个不同的列。例如:

add_column :messages, :sender_id, :integer
add_column :messages, :receiver_id, :integer

然后在模型中,这就是将每列映射到User类的逻辑发生的地方:

belongs_to :sender, :class_name => 'User'
belongs_to :receiver, :class_name => 'User'

当然,请为senderreceiver使用您自己的字词,但Rails会自动将sendersender_id列相关联({{1}的逻辑相同}})

然后,您就可以与用户receiveruser.sender进行互动。