Table has_many 中的名称通过关系

Table name in has_many through relation

我有一个模型,其中有一对夫妇通过关联寻找兄弟姐妹,即具有相同父项但不是其自身的记录。

class Person
  has_many :siblings, -> { where("being_siblings.id != beings.id") }, through: :beings, source: :self_and_related_beings
  has_many :nice_humans, through: :siblings, source: :human
end

我的问题是,如果我 运行 person.nice_humans 查询使用的连接 table 的名称与我时不同(在本例中类似于 being_nice_humans) 运行 person.siblings 在这种情况下它被称为 being_siblings。有什么方法可以告诉 rails 将 table 别名为什么或以其他方式使它起作用?

我已经尝试过类似 -> (p) { where.not("beings.id = ?", p.id) } 的方法,但我需要在 includes 中使用它,这在我传入实例时是不允许的。

注意:我的例子是基于一个真实的应用程序,但我有关联的名称。

非常感谢任何帮助!

您实际上无法定义这样的关联,因为关联的定义是 class 而不是实例级别。

虽然您可以使用 lambda 向关联添加默认范围,但 lambda 不接受参数,因为在加入、包括或急切加载关联时无法传递这些参数。 self 在 lambda 内部是一个关联代理而不是记录本身,所以你不能写 ->{ where.not(id: self.id) }.

你能做的就是写一个实例方法:

class Person < ApplicationRecord
  belongs_to :parent, optional: :true, 
                      class_name: 'Person'

  has_many :siblings, class_name: 'Person',
                      foreign_key: :parent_id,
                      primary_key: :parent_id
  
  def siblings
    # super is the getter created by the association
    super.where.not(id: self.id)
  end
end

用法示例:

irb(main):001:0> Person.all
  Person Load (0.2ms)  SELECT "people".* FROM "people" LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Person id: 1, name: "Odin", parent_id: nil, created_at: "2021-01-05 20:36:23", updated_at: "2021-01-05 20:36:23">, #<Person id: 2, name: "Thor", parent_id: 1, created_at: "2021-01-05 20:37:51", updated_at: "2021-01-05 20:37:51">, #<Person id: 3, name: "Balder", parent_id: 1, created_at: "2021-01-05 20:38:56", updated_at: "2021-01-05 20:38:56">]>
irb(main):002:0> Person.last.siblings
  Person Load (0.2ms)  SELECT "people".* FROM "people" ORDER BY "people"."id" DESC LIMIT ?  [["LIMIT", 1]]
  Person Load (0.2ms)  SELECT "people".* FROM "people" WHERE "people"."parent_id" = ? AND "people"."id" != ? LIMIT ?  [["parent_id", 1], ["id", 3], ["LIMIT", 11]]
=> #<ActiveRecord::AssociationRelation [#<Person id: 2, name: "Thor", parent_id: 1, created_at: "2021-01-05 20:37:51", updated_at: "2021-01-05 20:37:51">]>