Rails 4:推荐模型关联

时间:2017-09-15 17:31:04

标签: ruby-on-rails ruby-on-rails-4 associations

我正在创建一个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

2 个答案:

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