Aparichith
Aparichith

Reputation: 1535

Rails 5 association with different foreign key

I think I have missed something when creating an association with a foreign_key in Rails.

I have 2 models: Company and Employee. Company has_many employees and Employee belongs_to a company. Company has an attribute called company_code and I should be able to figure out which company the employee works for using the company_code instead of company_id.

At first, I created the models:

rails g model Company company_code:integer:index name

rails g model Employee joined:date:index salary:integer

Then, I generated a migration to add the company_code column to the employees table.

class AddReferenceToEmployee < ActiveRecord::Migration[5.1]
  def change
    add_column :employees, :company_code, :integer, index: true
    add_foreign_key :employees, :companies, column: :company_code
  end
end

And, finally I added the foreign key at the model level.

class Company < ApplicationRecord
  has_many :employees, foreign_key: :company_code
end

class Employee < ApplicationRecord
  belongs_to :company, foreign_key: :company_code
end

However, I'm still not able to create proper association.

company = Company.create(name: 'test', company_code: 123)
company.employees.create(joined: Date.today, salary: 1000)

It creates employee record with company_code = 1 instead of 123.

When I try to create a new instance of employee

company.employees.new

It will generate

#<Employee id: nil, joined: nil, salary: nil, created_at: nil, updated_at: nil, company_code: 1>

What am I missing? Is this the right way to do it?

Bellow is my schema.rb

ActiveRecord::Schema.define(version: 20180828052633) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "companies", force: :cascade do |t|
    t.integer "company_code"
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["company_code"], name: "index_company_on_company_code"
  end

  create_table "employees", force: :cascade do |t|
    t.date "joined"
    t.integer "salary"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "company_code"
  end

  add_foreign_key "employees", "companies", column: "company_code"
end

Upvotes: 0

Views: 214

Answers (1)

Priyanka Soni
Priyanka Soni

Reputation: 11

class Company < ApplicationRecord
  has_many :employees, primary_key: :company_code, foreign_key: :company_code
end

class Employee < ApplicationRecord
  belongs_to :company, foreign_key: :company_code, primary_key: :company_code
end

Upvotes: 1

Related Questions