3

In my rails project I have a namespaced has_many through relation Scheme

models/school/contact.rb

class School::Contact < ApplicationRecord

  belongs_to :school, class_name: '::School'

  has_many :school_contact_emails, class_name: 'School::Contact::Email'
  has_many :emails, through: :school_contact_emails, class_name: '::Email'

end

models/school/contact/email.rb

class School::Contact::Email < ApplicationRecord
  belongs_to :school_contact, class_name: 'School::Contact'
  belongs_to :email, class_name: '::Email'
end

models/email.rb

class Email < ApplicationRecord
  has_many :school_contact_emails, class_name: 'School::Contact::Email'
  has_many :school_contacts, through: :school_contact_emails, class_name: 'School::Contact'
end

If I open the rails console

s = School::Contact.first
=> #<School::Contact id: 1, name: "Headmaster Name", surname: "Headmaster Surname", school_contact_role_id: 1, school_id: 2285, created_at: "2018-06-24 17:47:21", updated_at: "2018-06-24 17:47:21", creator_id: 1, updater_id: 1>

If i look for the emails

s.emails
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR:  column school_contact_emails.contact_id does not exist)

It says that school_contact_emails.contact_id doesn't exist, but the table column should be "school_contact_id"

Here's the migration for the School::Contact::Email table

class CreateSchoolContactEmails < ActiveRecord::Migration[5.1]
  def change
    create_table :school_contact_emails do |t|
      t.references :school_contact, foreign_key: true
      t.references :email, foreign_key: true

      t.timestamps
      t.userstamps
    end
  end
end

Any type of help will be very appreciated

  • I have a feeling the issue is with the name of the foreign_key. Can you set `foreign_key: ` for the `School::Contact::Email` table's `belongs_to` entries? – shashwat Jun 25 '18 at 06:59

1 Answers1

2

You're very close with this - Rails actually expects the foreign key to reflect the name of the associated object's class + _id, in this case contact_id, rather than using the name of the association itself (in this case school_contact).

This gives you two options here: you can rename the column in your db, or you can add the foreign_key option to your association.

For example:

class School::Contact::Email < ApplicationRecord
  belongs_to :school_contact, class_name: 'School::Contact', foreign_key: 'school_contact_id'
  belongs_to :email, class_name: '::Email'
end

Hope that helps - let me know how you get on and shout if you have any questions.

SRack
  • 11,495
  • 5
  • 47
  • 60