使用自定义名称创建 Rails 联接 table

Making a Rails join table with custom names

我正在尝试在两个 AgentInfrastructure 模型之间创建连接 table (InfrastructureReferral),但使用的是自定义名称。

这是我的源代码:

环境

Rails version             4.2.6
Ruby version              2.3.3-p222 (x86_64-linux)

agent.rb

class Agent < ActiveRecord::Base
  has_many :infrastructure_referrals
  has_many :referrals, class_name: "Infrastructure", through: :infrastructure_referrals, foreign_key: "referral_id"
end

infrastucture.rb

class Infrastructure < ActiveRecord::Base    
  has_one  :infrastructure_referral
  has_one  :referral_agent, class_name: "Agent", through: :infrastructure_referral, foreign_key: "referral_agent_id"    
end

infrastructure_referral.rb

class InfrastructureReferral < ActiveRecord::Base    
  belongs_to :referral_agent, class_name: "Agent", foreign_key: "referral_agent_id"
  belongs_to :referrals, class_name: "Infrastructure", foreign_key: "referral_id"    
end

migration.rb

class CreateInfrastructureReferrals < ActiveRecord::Migration
  def change
    create_table :infrastructure_referrals do |t|
      t.integer :referral_agent_id
      t.integer :referral_id

      t.timestamps null: false
      t.datetime :deleted_at
    end

    add_foreign_key :infrastructure_referrals, :agents, column: :referral_agent_id
    add_foreign_key :infrastructure_referrals, :infrastructures, column: :referral_id

  end
end

正确创建table:

# \d infrastructure_referrals
                                            Table "public.infrastructure_referrals"
      Column       |            Type             | Collation | Nullable |                       Default
-------------------+-----------------------------+-----------+----------+------------------------------------------------------
 id                | integer                     |           | not null | nextval('infrastructure_referrals_id_seq'::regclass)
 referral_agent_id | integer                     |           |          |
 referral_id       | integer                     |           |          |
 created_at        | timestamp without time zone |           | not null |
 updated_at        | timestamp without time zone |           | not null |
 deleted_at        | timestamp without time zone |           |          |
Indexes:
    "infrastructure_referrals_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "fk_rails_05d9c83ed2" FOREIGN KEY (referral_id) REFERENCES infrastructures(id)
    "fk_rails_2b0ba51794" FOREIGN KEY (referral_agent_id) REFERENCES agents(id)

但是从 rails 控制台我无法与关系正确交互

[1] pry(main)> infrastructure = Infrastructure.find 1
    
[2] pry(main)> infrastructure.referral_agent
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column infrastructure_referrals.infrastructure_id does not exist
LINE 1: ...nfrastructure_referrals"."deleted_at" IS NULL AND "infrastru...
                                                             ^
: SELECT  "agents".* FROM "agents"
INNER JOIN "infrastructure_referrals"
ON "agents"."id" = "infrastructure_referrals"."referral_agent_id"
WHERE "infrastructure_referrals"."deleted_at" IS NULL
AND "infrastructure_referrals"."infrastructure_id" =  LIMIT 1

正确的指出infrastructure_referrals.infrastructure_id是错误的,应该是infrastructure_referrals.referral_id.

这是我尝试的第二天,但我不知道如何修复它。

感谢大家的帮助

我终于成功了!

class Agent < ActiveRecord::Base
  has_many :infrastructure_referrals, foreign_key: :referral_agent_id
  has_many :referrals, class_name: "Infrastructure", through: :infrastructure_referrals, source: :referral
end

class Infrastructure < ActiveRecord::Base    
  has_one :infrastructure_referral, foreign_key: :referral_id
  has_one :referral_agent, class_name: "Agent", through: :infrastructure_referral, source: :referral_agent 
end

class InfrastructureReferral < ActiveRecord::Base    
  belongs_to :referral, class_name: "Infrastructure"
  belongs_to :referral_agent, class_name: "Agent"   
end

class CreateInfrastructureReferrals < ActiveRecord::Migration
  def change
    create_table :infrastructure_referrals do |t|
      t.integer :referral_agent_id
      t.integer :referral_id

      t.timestamps null: false
      t.datetime :deleted_at
    end

    add_foreign_key :infrastructure_referrals, :agents, column: :referral_agent_id
    add_foreign_key :infrastructure_referrals, :infrastructures, column: :referral_id

  end
end