【问题标题】:How to make two foreign keys of same Model?如何制作相同型号的两个外键?
【发布时间】:2015-07-03 16:34:51
【问题描述】:

我有一个模型消息,它具有message:text | date_sent:date 作为属性。它还应该有 from_memberto_member 代表发送消息的用户和接收消息的用户。

如何在 Rails 中做到这一点?我已经读到,对于模型成员的 ForeignKey,约定将是 member_id。但是,如果我想要两个引用 Member 的字段怎么办?

【问题讨论】:

  • 您可以使您的 has_many / belongs_to 与自定义名称关联并指定外键。像 has_many :to_member, foreign_key: :to_member_id, class_name: 'Member' 之类的东西。感谢文档,我已经完成了这项工作,我会检查以找到链接。

标签: ruby-on-rails ruby ruby-on-rails-3 model foreign-keys


【解决方案1】:

您可以指定关联的类:

class Message < ActiveRecord::Base
  belongs_to :from_member, class_name: 'Member'
  belongs_to :to_member, class_name: 'Member'
end

class Member < ActiveRecord::Base
  has_many :sent_messages, class_name: 'Message', foreign_key: :from_member_id
  has_many :received_messages, class_name: 'Message', foreign_key: :to_member_id
end

在您的数据库中,:messages 需要属性 :from_member_id:to_member_id

所以在您的迁移中:

def change
  add_column :messages, :from_member_id, :integer
  add_column :messages, :to_member_id, :integer

  add_index :messages, :from_member_id
  add_index :messages, :to_member_id
end

【讨论】:

  • 是或指定您正在使用的foreign_key(有时不同的名称更清楚)
  • 好吧,Rails 是约定优于配置,所以不要配置约定所定义的内容。我明白你的意思。有时提示记住约定是件好事。
  • 是的,我完全同意。有趣的是,我们可以同时得到几乎相同的答案!我只是在迁移中添加一个索引,我想会有很多消息,检索发送者/接收者会更快
【解决方案2】:

我会做这样的事情(根据您的需要和代码清晰度调整错字):

message.rb

belongs_to :sender, foreign_key: :sender_id, class_name: 'Member'
belongs_to :receiver, foreign_key: :receiver_id, class_name: 'Member'


member.rb

has_many :message_sent, foreign_key: :sender_id, class_name: 'Message'
has_many :message_reveived, foreign_key: :receiver_id, class_name: 'Message'

然后你可以这样做:

@message.sender and @message.receiver

@member.message_sent and @member.message_reveived

对于您的迁移:

def change
  add_column :messages, :sender_id, :integer
  add_column :messages, :receiver_id, :integer
  add_index :messages, :sender_id
  add_index :messages, :receiver_id
end

【讨论】:

  • 发电机呢?如何指定字段?
  • 我通常手动添加这些,并在需要时添加索引。像 t.integer :sender_id, index: true
  • 生成器只是添加一个整数和一个索引。其余的来自 rails 约定(命名 ... )。手动复制很容易。
  • 对于生成器,您可以像这样指定索引:rails g model message sender_id:integer:index .....
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-23
  • 1970-01-01
  • 2022-08-12
  • 2019-01-21
  • 1970-01-01
  • 2011-03-20
相关资源
最近更新 更多