Eki Eqbal
Eki Eqbal

Reputation: 6017

has_many through relationship to the same Model

I have User table:

class User < ActiveRecord::Base
  has_many :broker_clients, :class_name => "BrokerClients", :foreign_key => "broker_id"
  has_many :clients, :through => :broker_clients, :foreign_key => "broker_id"
  has_many :brokers, :through => :broker_clients, :foreign_key => "client_id"
end

And BrokerClients table:

class BrokerClients < ActiveRecord::Base
  belongs_to :broker, class_name: "User"
  belongs_to :client, class_name: "User"
end

Now when I create a relationship:

>> BrokerClients.create(broker_id: User.first.id, client_id: User.last.id)
  User Load (9.7ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
  User Load (1.3ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
   (1.3ms)  BEGIN
  SQL (41.5ms)  INSERT INTO "broker_clients" ("broker_id", "client_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["broker_id", 4], ["client_id", 210], ["created_at", Fri, 10 Oct 2014 13:43:27 EDT -04:00], ["updated_at", Fri, 10 Oct 2014 13:43:27 EDT -04:00]]
   (0.5ms)  COMMIT
=> #<BrokerClients id: 1, broker_id: 4, client_id: 210, created_at: "2014-10-10 17:43:27", updated_at: "2014-10-10 17:43:27">
>> User.first.brokers.first

When I try to get clients it's working fine:

>> User.first.clients.first
  User Load (0.6ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
  User Load (1.2ms)  SELECT "users".* FROM "users" INNER JOIN "broker_clients" ON "users"."id" = "broker_clients"."
=> #<User id: 210, ....

But for the client when I try to get the brokers related to it wont work:

>> User.last.brokers.first
  User Load (0.7ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
  User Load (0.7ms)  SELECT "users".* FROM "users" INNER JOIN "broker_clients" ON "users"."id" = "broker_clients"."broker_id" WHERE "broker_clients"."broker_id" = $1 ORDER BY "users"."id" ASC LIMIT 1  [["broker_id", 210]]
=> nil

Any help ?

Upvotes: 0

Views: 59

Answers (2)

Shamsul Haque
Shamsul Haque

Reputation: 2451

Change in the User modal as:--

has_many :broker_clients, :class_name => "BrokerClients", :foreign_key => "broker_id"
has_many :clients, :through => :broker_clients, :foreign_key => "broker_id"

has_many :inverse_broker_clients, :class_name => "BrokerClients", :foreign_key => "client_id"
has_many :brokers, :through => :inverse_broker_clients, :foreign_key => "client_id"

Upvotes: 1

mattforni
mattforni

Reputation: 875

Look at your insert vs. your query:

Insert:

SQL (41.5ms) INSERT INTO "broker_clients" ("broker_id", "client_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["broker_id", 4], ["client_id", 210], ["created_at", Fri, 10 Oct 2014 13:43:27 EDT -04:00], ["updated_at", Fri, 10 Oct 2014 13:43:27 EDT -04:00]]

Queries:

User Load (0.7ms) SELECT "users".* FROM "users" INNER JOIN "broker_clients" ON "users"."id" = "broker_clients"."broker_id" WHERE "broker_clients"."broker_id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["broker_id", 210]]

You insert (broker_id=4, client_id=210) but you query for broker_id=210. That's why you're getting nil for brokers.first. Pretty sure you're foreign keys are backwards:

has_many :clients, :through => :broker_clients, :foreign_key => "broker_id"
has_many :brokers, :through => :broker_clients, :foreign_key => "client_id"

Should be

has_many :clients, :through => :broker_clients, :foreign_key => "client_id"
has_many :brokers, :through => :broker_clients, :foreign_key => "broker_id"

Hope that helps.

Upvotes: 0

Related Questions