clear icon indicating copy to clipboard operation
clear copied to clipboard

Problem with has_many through relation if the middle class doesn't have two foreign keys

Open anykeyh opened this issue 6 years ago • 4 comments

Current behavior of has_many through assume than the passthrough model table has two foreign keys bundled into the table.

However, in some case we want to call has_many through while the passed-through table has only one foreign key (or even non!).

An example would be this one:

class A
  include Clear::Model
  belongs_to b : B

  has_many c : C, through: B # << Error because B doesn't have the foreign key for A and C
end

class B
  include Clear::Model
  has_many a : A
  has_many c : C  
end

class C
  include Clear::Model
  belongs_to b : B
end

This fix won't be trivial and must be done before we go to polymorphic associations.

anykeyh avatar Mar 06 '19 13:03 anykeyh

I also have this issue

sam0x17 avatar Aug 19 '19 04:08 sam0x17

this was my workaround:

  def views
    View.query.inner_join("spaces"){ raw("views.space_id = spaces.id AND spaces.account_id = #{id}") }
  end

sam0x17 avatar Aug 19 '19 07:08 sam0x17

I think the rails way of viewing has_many: :through is it covers any situation where there is some model A, some intermediate model, B, and some model C, where B has either a has_many, has_one, or belongs_to association with C, and A has either a has_many, has_one, or belongs_to association with B, and rails will do whatever joins are necessary to find all the rows of C that are indirectly associated with A. So something like ~~9~~ 4 different join situations I think potentially. Would <3 <3 <3 if this was fully supported.

I think the most common situation in the wild is not the one that is currently supported but rather A has_many B which has_many C, which my snippet above supports.

sam0x17 avatar Aug 19 '19 18:08 sam0x17

update: here are the possible situations (I think):

  1. A => has_many => B => has_many => C
  2. A => has_one | belongs_to => B => has_many => C
  3. A => has_many => B => has_one | belongs_to => C
  4. A => has_one | belongs_to => B has_one | belongs_to => C

The last one is the one the library currently supports I believe.

sam0x17 avatar Aug 19 '19 19:08 sam0x17