简体   繁体   English

Rails 4:推荐模型关联

[英]Rails 4: Referral Model Associations

I am creating a referral model that will be able to link 2 clients, one that was referred and one that did the referring. 我正在创建一个referral模型,该模型将能够链接2个客户端,一个是被推荐的,另一个是进行推荐的。 I already have the client model, but am wondering the correct way to setup the referral model such that I can query: 我已经有了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

Setting up two associations to the same table is one of the trickiest associations in ActiveRecord. 在同一表中设置两个关联是ActiveRecord中最棘手的关联之一。 The key is to setup different associations for each foreign key column. 关键是为每个外键列设置不同的关联。

So lets start with the join table: 因此,让我们从联接表开始:

# 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

Lets setup the associations on Referral: 让我们在引荐上设置关联:

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

Nothing to funky here yet. 这里还没什么时髦的。 class_name: 'Client' tells ActiveRecord (AR) which table the association points to since it cannot be derived from the name of the assocation. class_name: 'Client'告诉ActiveRecord(AR)关联指向的表,因为它不能从关联的名称派生。 Now lets create the inverse associations on 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

To add the associations to other clients that are referred or referrers to a client use an indirect 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 tells AR to join through the assocation named :referrals . through: :referrals告诉AR通过名为:referrals的关联加入。
  • source: :referred indicates the assocation on the join table to use. source: :referred表示要使用的联接表上的关联。

You can use self association for this. 您可以为此使用自我关联。 On Client model, add referrals_id column. 在客户端模型上,添加referrals_id列。 The association in Client model would be like this : 客户模型中的关联如下所示:

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

Consider you have these two records in tables. 考虑您在表中有这两个记录。

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

Now you can query for referrals will returns all referrals where referrer has the client's id 现在,您可以查询引荐,将返回所有引荐具有客户ID的引荐

Client.find(1).referrals

This will generate a SQL like : 这将生成类似以下的SQL:

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

for referred_by will returns client that referred this client for Refered_by将返回引用此客户端的客户端

Client.find(2).referred_by

This will generate SQL like: 这将生成类似以下的SQL:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM