Home > other >  Custom Association in ruby on rails
Custom Association in ruby on rails

Time:09-22

I am finding it hard to understand some of the association defined in the code base.

class Patient < ApplicationRecord   
    belongs_to :g_district, class_name: "District", primary_key: "id", foreign_key: 'district_id', optional: true
    belongs_to :g_perm_district, class_name: "District", primary_key: "id", foreign_key: 'permanent_district_id', optional: true
    belongs_to :g_workplc_district, class_name: "District", primary_key: "id", foreign_key: 'workplace_district_id', optional: true    
end
class District
    belongs_to :province #, optional: true
    belongs_to :division, optional: true
    has_many :hospitals
    has_many :tehsils
    has_many :ucs
    has_many :mobile_users
    has_many :labs
    has_many :insecticides
end

I am not clearly getting these kind of associations defined her.(belongs_to :g_district, class_name: "District", primary_key: "id", foreign_key: 'district_id', optional: true).

In my code, there are no models like g_district, g_perm_district, g_workplc_district.

CodePudding user response:

This is simply creating an association with the same table with different names.

Here g_district, g_perm_district, g_workplc_district are associating with District model with the association names: g_dstrict with foreign_key district_id, g_perm_district with foreign_key permanent_district_id and g_workplc_district with foreign_key workplace_district_id

This basically states that Patients can have 3 districts- District, Permanent District, and Workplace District, as all these 3 are types of District, created an association with the same table with a different names.

Refer this blog for more details.

CodePudding user response:

Your code is associating the same model under different names. When in doubt you can always check this by looking at class_name: "District" which is referencing the actual class name.

In your case a Patient can have an association with three different districts (but all of them point to the District model):

3.times { District.create }
patient = Patient.create(
  g_district: District.find(1), 
  g_perm_district: District.find(2),
  g_workplc_district: District.find(3)
)

patient.g_district #=> #<District:0x00000001083ce048 id: 1,.. >
patient.g_perm_district #=> #<District:0x00000001083ce048 id: 2,.. >
patient.g_workplc_district #=> #<District:0x00000001083ce048 id: 3,.. >

It might also be worth checking the migrations or schema for Patient. The schema table might look like this:

create_table "patients", force: :cascade do |t|
    t.integer "district_id"
    t.integer "permanent_district_id"
    t.integer "workplace_district_id"
    (...other columns here...)
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
end

and the migration:

class CreatePatients < ActiveRecord::Migration[7.0]
  def change
    create_table :patients do |t|
      t.integer :district_id
      t.integer :permanent_district_id
      t.integer :workplace_district_id
      (...other columns here...)

      t.timestamps
    end
  end
end

The foreign_key: 'district_id' part (as well as the other two) suggests that these columns must exist and helps ActiveRecord properly associate the same model multiple times

  • Related