# How to properly set association to a self junction table?

**URL:** https://discourse.rom-rb.org/t/how-to-properly-set-association-to-a-self-junction-table/696
**Category:** Uncategorized
**Created:** [May 22, 2025, 2:10pm UTC](https://discourse.rom-rb.org/t/how-to-properly-set-association-to-a-self-junction-table/696 "2025-05-22T14:10:16Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![Franck](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.rom-rb.org/franck/32/349_2.png) [@Franck](https://discourse.rom-rb.org/u/Franck)
#### Post date: [May 22, 2025, 2:10pm UTC](https://discourse.rom-rb.org/t/how-to-properly-set-association-to-a-self-junction-table/696/1 "2025-05-22T14:10:17Z")

</div>

Hi there,  
I’m trying to figure out my association setting. Here is a MWE :  
A users table, and a mentoring table. Each user can mentor any number of other users (mentees). And each mentee could be mentored by any number of other users (mentors).

- Migration :

```auto
ROM::SQL.migration do
  change do
    create_table :users do
      primary_key :id
      column :name, String, null: false
    end

    create_table :mentoring do
      primary_key :id
      foreign_key :mentor_id, :users, null: false # eventually here unique: true if only one mentor allowed
      foreign_key :mentee_id, :users, null: false
    end
  end
end

```

- seeds :

```auto
users : [
 {:id=>1, :name=>"Alice"},
 {:id=>2, :name=>"Bob"},
 {:id=>3, :name=>"Chuck"},
 {:id=>4, :name=>"Doug"},
 {:id=>5, :name=>"Erny"}
]
mentoring : [
 {:id=>1, :mentor_id=>1, :mentee_id=>2},
 {:id=>2, :mentor_id=>1, :mentee_id=>3},
 {:id=>3, :mentor_id=>2, :mentee_id=>3},
 {:id=>4, :mentor_id=>3, :mentee_id=>4},
 {:id=>5, :mentor_id=>2, :mentee_id=>5}
]

```

- relations :

```auto
schema :users, infer: true do
  associations do
    has_many :mentees, through: :mentoring, foreign_key: :mentor_id, relation: :users, as: :mentees
    has_many :mentors, through: :mentoring, foreign_key: :mentee_id, relation: :users, as: :mentors
  end
end

schema :mentoring, infer: true do
  associations do
    belongs_to :mentee, foreign_key: :mentee_id, relation: :users
    belongs_to :mentor, foreign_key: :mentor_id, relation: :users # this seems to fail ! 
  end
end

```

Then :

- `users.combine(:mentees).to_a` leads to the expected result :

```auto
[
 {:id=>1, :name=>"Alice", :mentees=> [{:id=>2, :name=>"Bob", :mentor_id=>1}, {:id=>3, :name=>"Chuck", :mentor_id=>1}]},
 {:id=>2, :name=>"Bob", :mentees=> [{:id=>3, :name=>"Chuck", :mentor_id=>2}, {:id=>5, :name=>"Erny", :mentor_id=>2}]},
 {:id=>3, :name=>"Chuck", :mentees=>[{:id=>4, :name=>"Doug", :mentor_id=>3}]},
 {:id=>4, :name=>"Doug", :mentees=>[]},
 {:id=>5, :name=>"Erny", :mentees=>[]}
]

```

- `users.combine(:mentors).to_a` leads to a curious result. Mentor numbers are correct but their identity is “replaced by” meetee identity. I think this is because only one `belongs_ to` statement (the first) is taken into account. Commenting out this first `belongs_to` statement leads to things changed : I can obtain mentors but not mentees.

```auto
[
 {:id=>1, :name=>"Alice", :mentors=>[]},
 {:id=>2, :name=>"Bob", :mentors=>[{:id=>2, :name=>"Bob", :mentee_id=>2}]},
 {:id=>3, :name=>"Chuck", :mentors=> [{:id=>3, :name=>"Chuck", :mentee_id=>3}, {:id=>3, :name=>"Chuck", :mentee_id=>3}]},
 {:id=>4, :name=>"Doug", :mentors=>[{:id=>4, :name=>"Doug", :mentee_id=>4}]},
 {:id=>5, :name=>"Erny", :mentors=>[{:id=>5, :name=>"Erny", :mentee_id=>5}]}
]

```

Anyone to help me fixing this ? Any advice/guide on relation options usage (:source, :target, :relation, etc.) ?

Thanks !

---

<div class="post-metadata">

### Author: ![Franck](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.rom-rb.org/franck/32/349_2.png) [@Franck](https://discourse.rom-rb.org/u/Franck)
#### Post date: [May 23, 2025, 6:59am UTC](https://discourse.rom-rb.org/t/how-to-properly-set-association-to-a-self-junction-table/696/2 "2025-05-23T06:59:33Z")

</div>

The night was good for me. The solution is to tie 2 relations to the mentoring table, correctly aliased. See :

```auto
# relations/user_mentees.rb
schema :mentoring, as: :user_mentees, infer: true do
  associations do
    belongs_to :mentee, foreign_key: :mentee_id, relation: :users
  end
end

```

```auto
# relations/user_mentors.rb
schema :mentoring, as: :user_mentors, infer: true do
  associations do
    belongs_to :mentor, foreign_key: :mentor_id, relation: :users
  end
end

```

then,

```auto
# relations/users.rb
schema :users, infer: true do
  associations do
    has_many :mentees,
      through: :user_mentees,
      foreign_key: :mentor_id,
      relation: :users,
      as: :mentees

    has_many :mentors,
      through: :user_mentors,
      foreign_key: :mentee_id,
      relation: :users,
      as: :mentors
  end
end

```

I now enjoy seeing `users.combine(:mentees).to_a` together with `users.where(name: 'Bob').combine(:mentees).to_a` in one hand, and `users.combine(:mentors).to_a` together with `users.where(name: 'Bob').combine(:mentors).to_a` in another hand, working like a charm.
