2017-09-15 152 views
1

我正在創建一個referral模型,該模型能夠鏈接2個客戶端,一個是被引用的,一個是引用的。我已經有client模式,但我想知道,以建立正確的方式referral模型,這樣我可以查詢:導軌4:推薦模型關聯

Client.find(x).referrals 
# returns all referrals where referrer has the client's id 

Client.find(x).referred_by 
# returns client that referred this client 
+0

我建議你使用你試圖連接表http://guides.rubyonrails.org/active_record_migrations.html#creating-a-join-table –

+1

似乎做一個多對多的關聯,引用作爲連接表。 – EJ2015

回答

2

兩個協會建立的同桌是ActiveRecord的最棘手的協會之一。關鍵是爲每個外鍵列設置不同的關聯。

所以,讓我們開始與聯接表:

# This is a Rails 5 migration - don't copy paste it 
# You'll have to generate one for rails 4 
class CreateReferrals < ActiveRecord::Migration[5.0] 
    def change 
    create_table :referrals do |t| 
     t.belongs_to :referrer_id, foreign_key: false 
     t.belongs_to :referred_id, foreign_key: false 
     # Since the table for the foreign key cannot be automatically derived you need to add them manually 
     add_foreign_key :referrals, :clients, column: :referrer_id 
     add_foreign_key :referrals, :clients, column: :referred_id 
     t.timestamps 
    end 
    end 
end 

允許設置上推薦的關聯:

class Referral < < ActiveRecord::Base 
    belongs_to :referrer, class_name: 'Client' 
    belongs_to :referred, class_name: 'Client' 
end 

還沒有在這裏時髦。 class_name: 'Client'告訴ActiveRecord(AR)該關聯指向哪個表,因爲它不能從關聯的名稱派生。現在,讓我們在客戶端建立逆協會:

class Client < ActiveRecord::Base 
    has_many :referrals, class_name: 'Referral', 
    foreign_key: 'referrer_id' 
    has_many :referrals_as_referred, class_name: 'Referral', 
    foreign_key: 'referred_id' 
end 

向消協添加到被稱爲或引薦給客戶使用間接ASSOCATION其他客戶:

class Client < ActiveRecord::Base 
    # ... 
    # clients reffered by this client 
    has_many :referred_clients, 
     through: :referrals, 
     source: :referred 
    has_many :referrers, 
     through: :referrals_as_referred, 
     source: :referrer 
end 
  • through: :referrals告訴AR加盟通過名爲:referrals的關聯。
  • source: :referred指示要使用的連接表上的關聯。
+0

@DavidAldridge你是對的。編輯 – max

+0

真的很感謝徹底的迴應。這比我預想的要複雜得多 –

0

您可以使用自我關聯。在客戶端模型上,添加referrals_id列。客戶端模型中的關聯將如下所示:

class Client < ActiveRecord::Base 
    has_many :referrals, class_name: "Client", foreign_key: :referrals_id 
    belongs_to :referred_by, class_name: "Client", foreign_key: :referrals_id 
end 

考慮在表中有這兩條記錄。

[{ 
    "id":1, 
    "name":"Admin", 
    "referrals_id": nil, 
}, 
{ 
    "id":2, 
    "name":"Client", 
    "referrals_id":1, 
}] 

現在,您可以查詢推介會返回所有推薦其中引用了客戶端的ID

Client.find(1).referrals 

這將產生像SQL:

`SELECT "clients".* FROM "clients" WHERE "clients"."referrals_id" = ? [["referrals_id", 1]]` 

爲referred_by將返回客戶端,提到這個客戶

Client.find(2).referred_by 

這將生成SQL這樣的:

SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]