我正在创建一个referral
模型,该模型将能够链接2个客户端,一个被引用的客户端和一个执行引用的客户端。我已经拥有client
模型,但我想知道设置referral
模型的正确方法,以便我可以查询:
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 :(得分: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)关联指向哪个表,因为它不能从关联的名称派生。现在让我们在Client上创建反向关联:
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
要将关联添加到被引用的其他客户端或引用到客户端,请使用间接关联:
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
表示要使用的连接表的关联。 答案 1 :(得分: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,
}]
现在,您可以查询推介将返回所有推荐,其中referrer具有客户端ID
Client.find(1).referrals
这将生成如下的SQL:
`SELECT "clients".* FROM "clients" WHERE "clients"."referrals_id" = ? [["referrals_id", 1]]`
for referenced_by将返回引用此客户端的客户端
Client.find(2).referred_by
这将生成如下的SQL:
SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]