Rails:使用 has_and_belongs_to_many 的自连接方案? [英] Rails: self join scheme with has_and_belongs_to_many?

查看:53
本文介绍了Rails:使用 has_and_belongs_to_many 的自连接方案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个 Users 的结构,它有很多 friends,也是 User 类:

I would like to create a structure of Users having many friends, also of class User:

class User < ActiveRecord::Base
  has_and_belongs_to_many :friends, class_name: "User"
end

我不需要他们关系的任何细节,因此我不使用带有 Friendship 类的 :through.但是现在我找不到任何方法来创建相应的数据库(既不使用迁移文件也不使用 rails g model User username:string ... 命令).有什么想法吗?

I do not need any details of their relationship thus I do not use :through with kind of class Friendship. But now I cannot find any way how to create corresponding database (neither with migration file nor using rails g model User username:string ... command). Any ideas?

推荐答案

以下是一些可能有用的资源:

Here are some resources which may be helpful:

  • RailsCasts episode #163 Self-Referential Association regarding self-referential many-to-many relationships
  • RailsCasts episode #47 Two Many-to-Many. This might be more relevant to what you're attempting to accomplish
  • A gist someone created for self-referential relationships using HABTM

我将总结在这些链接中找到的信息:

I'll summarize the information found in those links:

鉴于您正在描述一种自引用的多对多关系,您当然最终会得到一个连接表.通常,连接表的命名方式应该让 Rails 自动找出该表连接的模型,但是自引用"部分使这有点尴尬,但并不困难.您只需指定连接表的名称以及连接列.

Given that you're describing a self-referential many-to-many relationship, you will of course end up with a join table. Normally, the join table should be deliberately named in such a way that Rails will automatically figure out which models the table is joining, however the "self-referential" part makes this a tad awkward, but not difficult. You'll merely have to specify the name of the join table, as well as the joining columns.

您需要使用可能如下所示的迁移来创建此表:

You'll need to create this table using a migration that will probably look something like this:

class CreateFriendships < ActiveRecord::Migration
  def self.up
    create_table :friendships, id: false do |t|
      t.integer :user_id
      t.integer :friend_user_id
    end

    add_index(:friendships, [:user_id, :friend_user_id], :unique => true)
    add_index(:friendships, [:friend_user_id, :user_id], :unique => true)
  end

  def self.down
      remove_index(:friendships, [:friend_user_id, :user_id])
      remove_index(:friendships, [:user_id, :friend_user_id])
      drop_table :friendships
  end
end

我不确定是否有创建此表的快捷方式,但您至少可以简单地执行rails g migration create_friendships,并填写self.upself.down 方法.

I'm not certain whether there is a shortcut way of creating this table, but bare minimum you can simply do rails g migration create_friendships, and fill in the self.up and self.down methods.

最后在您的用户模型中,您只需添加连接表的名称,如下所示:

And then finally in your user model, you simply add the name of the join table, like so:

class User < ActiveRecord::Base
  has_and_belongs_to_many :friends, 
              class_name: "User", 
              join_table: :friendships, 
              foreign_key: :user_id, 
              association_foreign_key: :friend_user_id
end

如您所见,虽然您在数据库中有一个连接表,但没有相关的连接模型.

As you can see, while you do have a join table in the database, there is no related join model.

请告诉我这是否适合您.

Please let me know whether this works for you.

这篇关于Rails:使用 has_and_belongs_to_many 的自连接方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆