Search code examples
ruby-on-railsactiverecordhas-and-belongs-to-manyjoin

has_and_belongs_to_many issue with table_name_prefix


ich would like to ask for some help with has_and_belongs_to_many association.

I have the following tables and models:

candidate_job_title_translations -> Candidate::JobTitleTranslation (in a subfolder with table_name_prefix )

create_table "candidate_job_title_translations", force: :cascade do |t|
end

profile_experiences, ProfileExperience

create_table "profile_experiences", id: :serial, force: :cascade do |t|
end

candidate_job_title_translations_profile_experiences, No model

create_table "candidate_job_title_translations_profile_experiences", id: false, force: :cascade do |t|
    t.bigint "candidate_job_title_translation_id", null: false
    t.bigint "profile_experience_id", null: false
end

The two models are setuped for the association:

class ProfileExperience < ApplicationRecord
   has_and_belongs_to_many :candidate_job_title_translations, class_name: 'Candidate::JobTitleTranslation'
end

class Candidate::JobTitleTranslation < ApplicationRecord
   has_and_belongs_to_many :profile_experiences, class_name: 'ProfileExperience'
end

My Problem now is, I get a ActiveRecord error, saying job_title_translation_id does not exist, which is correct. It should look for candidate_job_title_translation_id

ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column candidate_job_title_translations_profile_experiences.job_title_translati
on_id does not exist
LINE 1: ...ces" ON "candidate_job_title_translations"."id" = "candidate...

I have the feeling I can solve it by not having the table_name_prefix and model structure but, that is not good in terms of my structure. Maybe you have an idea.

Thanks


Solution

  • Thats not really a good domain model to start with.

    If you want a translations table you want to do it something like:

    class Position
      belongs_to :title
      has_many :translated_titles, 
        through: :title,
        source: :translations
    end
    
    class Title
      has_many :positions
      has_many :translations, 
        class_name: 'Titles::Translation'
    end
    
    class Titles::Translation
      belongs_to :title
    end
    

    You should be more concerned about creating meaningful relations and duplication than "I don't want to have another class, waaah" which is the most common reason for choosing HABTM.

    Also when "namespacing" models in Rails the module should be plural:

    Good: Titles::Translation
    Bad: Title::Translation

    This convention is due to the way that ActiveRecord maps tables to tables to classes and the fact that nesting your model inside another model class is not really a good idea.