I've got in this current situation two models; Country and Province and I'm trying to create a relationship between these two models in a 1:M relationship. The problem I'm having is I can't get a migration to correctly create the relationship when I generate the models as such:
class CreateCodeTableCountries < ActiveRecord::Migration[7.0]
def change
create_table :countries, primary_key: "country_code", id: { type: :string, limit: 2 }, force: :cascade do |t|
t.string :screen_label, limit: 80, null: false
t.boolean :is_active, default: true, null: false
t.integer :display_order, limit: 2, default: 10, null: false
end
end
end
class CreateCodeTableProvinces < ActiveRecord::Migration[7.0]
def change
create_table :provinces, primary_key: "province_code", id: { type: :string, limit: 20 }, force: :cascade do |t|
t.string :country_code, limit: 20, null: false
t.references :countries
t.string :screen_label, limit: 80, null: false
t.boolean :is_active, default: true, null: false
t.integer :display_order, limit: 2, default: 10, null: false
end
end
end
In this instance the migration creates the table but not the relationship between Country and Province. If I try and create a new Province
country.provinces.create!(province_code: item["provinceCode"], country_code: country["country_code"], screen_label: item["screenLabel"], is_active: item["isActive"], display_order: item["displayOrder"])
doing so results in an error that doens't make much sense given I've specified a primary key on the Country model as country_code
:
ActiveModel::UnknownAttributeError: unknown attribute 'country_id' for CodeTable::Province.
raise UnknownAttributeError.new(self, k.to_s)
^^^^
however if I instead do the following I have no problems, the Province is created successfully, but again there's no reference and relationship between the two models
CodeTable::Province.create!(province_code: item["provinceCode"], country_code: country["country_code"], screen_label: item["screenLabel"], is_active: item["isActive"], display_order: item["displayOrder"])
Where things start making a bit more sense is if I create my Province migration as follows:
class CreateCodeTableProvinces < ActiveRecord::Migration[7.0]
def change
create_table :provinces, primary_key: "province_code", id: { type: :string, limit: 20 }, force: :cascade do |t|
t.string :country_code, limit: 2, null: false
t.string :screen_label, limit: 80, null: false
t.boolean :is_active, default: true, null: false
t.integer :display_order, limit: 2, default: 10, null: false
end
add_foreign_key :provinces, :countries, column: "country_code", primary_key: "country_code", name: "country_province_fk"
# add_foreign_key :provinces, :countries, column: :country_code, primary_key: "country_code"
end
end
This creates the table, and setups the foreign key correctly between the two tables, that is until I again try to create a new Province and I keep getting the same error message about the unknown attribute 'country_id'
In my Country and Province models they've been defined as:
class CodeTable::Country < ApplicationRecord
self.primary_key = "country_code"
has_many :provinces
end
and
class CodeTable::Province < ApplicationRecord
self.primary_key = "province_code"
belongs_to :country, foreign_key: "country_code"
end
At this point I have no idea what it is that I'm doing wrong, or why rails insists on using an id that isn't defined or created.
I also understand this isn't the "rails" way but at the same time this is how my database is designed, and this is a common pattern that I don't want to change.