Skip to content

Rails – multiple columns to the same table’s foreign key

Ruby on Rails is beautiful! It does seem confusing at the beginning but it offers quick solutions to issues which may get quite complicated in some other development frameworks.

I have a table relation where multiple columns of the same table refer to the same foreign key. In this case has_many and belongs_to does not directly cut it. There is, however, a very easy solution.

Here is the situation, I have a table which lists languages


id name
1 English
2 Polish
. .
. .

Then I have the table which lists the language pairs for a user:


user_id source_language_id target_language_id
1 1 2
1 2 3
. . .
. . .

As you guessed, both the source_language and target_language columns map to the same key, the id column of the languages table. This is how you map this relation in rails:


class Language < ActiveRecord::Base

has_many :occurances_as_source_language, :class_name => “LanguagePair”, :foreign_key => “source_language_id”
has_many :occurances_as_target_language, :class_name => “LanguagePair”, :foreign_key => “target_language_id”



class LanguagePair < ActiveRecord::Base

belongs_to :source_language, :class_name => “Language”, :foreign_key => “source_language_id”
belongs_to :target_language, :class_name => “Language”, :foreign_key => “target_language_id


By doing this I am able to map both columns that I have in my language pairs table to the languages table’s id column. After this, things are super easy and instances below work as expected: #returns the name of the language that corresponds to source_language_id #returns the name of the language that corresponds to target_language_id

Multiple foreign keys and Rails? Easy! Happy coding!

Categories: Ruby On Rails.

Tags: , , ,

Comment Feed

7 Responses

  1. hello
    thanks for making this post
    I have a question.
    How did you define two model, language and language pair in db?(db-migration files)

    Jongwon ChaeFebruary 21, 2012 @ 8:23 amReply
    • Jongwon, this was just example that I used to explain the situation and the required models. I do not have an actual database migration for this one. What is the problem that you are having?

  2. it’d be great if u explained what the migration would look like as well 😉 i got as far as mapping at the class level, but not having any luck with the actual migration 🙁

  3. oh nevermind, i got it ;D thx man

  4. Hi! Thanks for the post, it helped me a lot. 🙂

    Although I would like to ask you if you know of a “better” way to do something like this? I’m thinking of something that would use joins (your approach uses separate SELECT queries). If you had a list of 20 language pairs, your approach would create 20 x 2 SELECT queries.

    • With a few exceptions of course – some Languages will be loaded from cache if they were fetched previously on the same page load.

  5. Thanks!
    bunlarda takılmak kötü oluyor fakat cevabını öğrenince biraz daha kolaylaşıyor, teşekkürler.

Some HTML is OK

or, reply to this post via trackback.