2

相互に参照できる顧客のリストを表す自己結合テーブルを作成しようとしています (おそらく製品またはプログラム)。モデルを「Customer」という 1 つのクラスだけに制限しようとしています。

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

顧客のrefering_customerへのアクセスに問題はありません:

@customer.referring_customer.name

... @customer を参照した顧客の名前を返します。

ただし、参照にアクセスするときに空の配列を取得し続けます。

@customer.referrals

... 戻り値 []。

私は binding.pry を実行して、実行されている SQL を確認しました。「リファラー」があり、複数のリフェラルが必要な顧客の場合です。実行中の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 を referral_customer_id として持つ顧客であるすべての紹介の配列を返す必要があります。

TL;DR 1 つのクラスのみを使用して自己結合は可能ですか? その場合、クエリが has_many 関係の正しいデータを取得できるように、条件と外部キーを設定するにはどうすればよいですか?

4

1 に答える 1

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" 

これは、顧客テーブルの refering_customer_id 列を使用します。

于 2013-11-06T03:59:06.793 に答える