user1943735
user1943735

Reputation: 155

How do you get the type when using Table Per Type inheritance in Ruby on Rails?

I have a couple of classes that look like this:

Person {
    id(PK)
    first_name string
    last_name string
}

class Employee {
    person_id(FK)
    job_description string
}

class Student {
    person_id(FK)
    school_name string
}

If I had a large list of People, how could I figure out what type each of them are without having to do

Student.where(person_id = person.id).any?

and

Employee.where(person_id = person.id).any?

for every "person" in the list?

I need to do a similar operation very often, so would Single Table Inheritance be a better choice?

Upvotes: 1

Views: 207

Answers (2)

Matthew Rudy
Matthew Rudy

Reputation: 16844

It looks like what you're trying to implement is Class Table Inheritance.

(See earlier questions. eg. "Class Table Inheritance in Rails 3")

There are various gems trying to implement this, and they each have their own opinions.

Fundamentally if all you know is the "person_id" then you will always need to look up the other tables to find which class it is.

The simplest way you can do this without changing anything fundamental is to use rails' has_one to create a cached relation between the two tables.

class Person
  has_one :employee_details, class_name: "Employee"
  has_one :student_details, class_name: "Student"

  def employee?
    employee_details.present?
  end

  def student?
    student_details.present?
  end
end

Importantly a Person can be both an employee and a student.

If that is not the case, then I suggest you look at Rails' Single Table Inheritance, or consider another way of implementing the same.

Upvotes: 1

ilan berci
ilan berci

Reputation: 3881

If it's Ruby on Rails (ActiveRecord)

class Person < ActiveRecord::Base has_many :employees has_many :students end

class Employee belongs_to :person end

class Student belongs_to :person end

Person.find(person_id).students.any? Person.find(person_id).employees.any?

Also, for the record, I am just answering the question as you phrased it. I think a better design would be to have a class called (Role) and have Employee and Student extend from that so you could have a many to many association to Role so a person could be both a student(s) and an employee(s) which is entirely possible

Upvotes: 0

Related Questions