如何在Rails中使用ActiveRecord在单个类中创建自引用关联(自联接)?

时间:2013-11-06 03:51:43

标签: ruby-on-rails activerecord self-join self-reference

我正在尝试创建一个自联接表,表示可以互相推荐的客户列表(可能是产品或程序)。我试图将我的模型限制在一个类“客户”。

TL; DR 位于底部。

架构是:

  create_table "customers", force: true do |t|
    t.string   "name"
    t.integer  "referring_customer_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "customers", ["referring_customer_id"], name: "index_customers_on_referring_customer_id"

我的模特是:

class Customer < ActiveRecord::Base
  has_many :referrals, class_name: "Customer", foreign_key: "referring_customer_id", conditions: {:referring_customer_id => :id}
  belongs_to :referring_customer, class_name: "Customer", foreign_key: "referring_customer_id"
end

访问客户的refer_customer时没问题:

@customer.referring_customer.name

...返回引用@customer的客户名称。

但是,在访问引荐时,我一直得到一个空数组:

@customer.referrals

...返回[]。

我运行binding.pry来查看正在运行的SQL,给定一个拥有“referer”且应该有多个推介的客户。这是正在执行的SQL。

      Customer Load (0.3ms)  SELECT "customers".* FROM "customers"
WHERE "customers"."id" = ? ORDER BY "customers"."id"
ASC LIMIT 1  [["id", 2]]

      Customer Exists (0.2ms)  SELECT 1 AS one FROM "customers"
WHERE "customers"."referring_customer_id" = ? AND
"customers"."referring_customer_id" = 'id' LIMIT 1 
[["referring_customer_id", 3]]

我有点失落,不确定我的问题在哪里。我不认为我的查询是正确的 - @ customer.referrals应返回所有引荐的数组,这些引用是将@ customer.id作为其refer_customer_id的客户。

TL; DR 只使用一个类可以进行自联接吗?如果是这样,我如何设置我的条件和外键,以便我的查询能够获得has_many关系的正确数据?

1 个答案:

答案 0 :(得分:4)

此关联定义

has_many :referrals, class_name: "Customer", foreign_key: "referring_customer_id", conditions: {:referring_customer_id => :id}

不太对劲。没有必要定义条件子句 - 这是has_many的重点。它应该是:

has_many :referrals, class_name: "Customer", foreign_key: "referring_customer_id" 

将使用customers表上的refer_customer_id列。