How do I create a self referential association (self join) in a single class using ActiveRecord in Rails?

StackOverflow https://stackoverflow.com/questions/19803759

문제

I am trying to create a self join table that represents a list of customers who can refer each other (perhaps to a product or a program). I am trying to limit my model to just one class, "Customer".

TL;DR available at bottom.

The schema is:

  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"

My model is:

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

I have no problem accessing a customer's referring_customer:

@customer.referring_customer.name

... returns the name of the customer that referred @customer.

However, I keep getting an empty array when accessing referrals:

@customer.referrals

... returns [].

I ran binding.pry to see what SQL was being run, given a customer who has a "referer" and should have several referrals. This is the SQL being executed.

      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]]

I'm a bit lost and am unsure where my problem lies. I don't think my query is correct -- @customer.referrals should return an array of all the referrals, which are the customers who have @customer.id as their referring_customer_id.

TL;DR Are self joins possible using only one class? If so, how do I set up my conditions and foreign keys so that my queries get me the correct data for the has_many relationship?

도움이 되었습니까?

해결책

This association definition

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

isn't quite right. There's no need to define the conditions clause - that's the whole point of the has_many. It should be:

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

which will use the referring_customer_id column on the customers table.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top