【问题标题】:Rails HABTM with join table get non associated records带有连接表的 Rails HABTM 获取非关联记录
【发布时间】:2025-12-11 22:50:01
【问题描述】:

我正在使用带有 postgresql 9.6 的 Rails 5。我有以下模型和关系

表格

  1. 细分
  2. people_segments(连接表)

关系

人:

has_and_belongs_to_many :segments, through: :people_segments 

细分:

has_and_belongs_to_many :people, through: :people_segments 

在这里,我想获取与特定细分无关的人。我尝试使用 join 但无法获得结果。现在我正在使用“不在”查询,这需要更多时间。不使用“not in”还有其他方法吗?

【问题讨论】:

  • "这里我想获取与特定段无关的人。我尝试使用 join 但无法获得结果。" -> 你写的 Activerecord 查询是什么,你期望什么,你得到了什么?

标签: sql ruby-on-rails has-and-belongs-to-many


【解决方案1】:

你的对象是错误的

模型是person,表格是people

模型 Person.rb

has_and_belongs_to_many :segments

模型段.rb

has_and_belongs_to_many :people

迁移看起来像这样

class CreatePeopleAndSegments < ActiveRecord::Migration[5.0]
  def change
    create_table :people do |t|
      t.string :name
      t.timestamps
    end

    create_table :segments do |t|
      t.string :part_number
      t.timestamps
    end

    create_table :people_segments, id: false do |t|
      t.belongs_to :person, index: true
      t.belongs_to :segment, index: true
    end
  end
end

因此,当您执行@person.segments 时,您会得到一个包含所有段的数组viceversa @segment.people

在这里,我想获取与特定细分无关的人。我尝试使用 join 但无法获得结果。现在我正在使用“不在”查询,这需要更多时间。不使用“not in”还有其他方法吗?

在两个表之间已经有一个Join,也许您最好的选择是确保您可以在应用程序端将该连接用作Model

rails 的 association_basics 指南中有专门的章节讨论这个问题,称为choosing-between-has-many-through-and-has-and-belongs-to-many

我引用它们

最简单的经验法则是如果您需要将关系模型作为独立实体使用,则应该设置一个 has_many :through 关系。如果您不需要对关系模型做任何事情,那么设置 has_and_belongs_to_many 关系可能会更简单(尽管您需要记住在数据库中创建连接表)。

我相信,如果您阅读了该章节,您会明白对您来说最好的选择是使用has_many :through 并在您的应用程序中拥有一个代表表people_segments 的对象。

创造性地思考这种关系是什么,peoplesegments之间的这种关系是role还是position...

要实现has_many :through,您可以关注guide

完成后,您可以使用Position 对象进行查询。

Position.where.not(segment_id: 1)

如果这不是您需要的,rails query documentation 包含更多信息,并且 * 不会替代官方文档

【讨论】:

  • @anandh 这不能解决您的问题吗?你为什么不接受回复?谢谢
  • 是的,你的回答没有解决我的问题。但我投票支持你的努力。仍在寻找解决方案...