I'm trying to create a join table (InfrastructureReferral
) between the two Agent
and Infrastructure
models, but using custom names.
This is my source code:
Environment
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
The table is created correctly:
# \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)
but from the rails console I can't interact correctly with the relationship
[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" = $1 LIMIT 1
Rightly it is pointed out that infrastructure_referrals.infrastructure_id
is wrong, it should be infrastructure_referrals.referral_id
.
It's the second day I'm trying, but I have no idea how to fix it.
Thank you all for any help
CodePudding user response:
I finally succeeded!
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