Rails 5 - Object Relation Impedence and how to structure multiple inherited classes/tables

后端 未结 3 1762
Happy的楠姐
Happy的楠姐 2021-01-18 12:42

EDIT I have edited this from the original to make it easier to understand.


I understand the Object Relationship Impedance problem. I understan

相关标签:
3条回答
  • 2021-01-18 13:10

    I found a solution to my first Question. Leaving the models setup as they are in the question, I change the database to see if it would work.

    I changed the Assignment table so that the foreign_key is now called 'employee_id' since Rails seemed to want to insist on that.

    Then I changed the constraint, which now reads:

    ALTER TABLE public.assignments
      ADD CONSTRAINT fk_rails_52f37556f9 FOREIGN KEY (employee_id)
          REFERENCES public.people (id) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE NO ACTION;
    

    Then the code works - but of course I would now have to write a migration script to create such a constraint.

    The original migration does not work, as it creates 'person_id':

      t.references :person, foreign_key: true
    

    This answer made it clear that Rails does not properly support foreign keys. SIGH

    The other problem with this solution is that if other subtypes of Person at some point in the future need to also be assigned to Projects, they can't be. So not a great solution really. Better to leave assignments related directly to Person.

    0 讨论(0)
  • 2021-01-18 13:14
    1. On the migration, drop the FK constraints on the addressses table. On the child classes redefine the has_many relation and specify :foreign_key & :foreign_type.

    2. On your Assignment serializer, specify the belongs_to :employee, AMS should handle it correctly.

      Also take a look at the :source and :source_type options of the has_many association.

    0 讨论(0)
  • 2021-01-18 13:29

    I'll answer your first question as it to me is the main question. To me there is a clue when its asking for an employees table on migration.

    This won't work. The migration will fail, since there is no table called Employee to create the foreign-key constraints on. STI means that the 'base class' is the People table.

    This would indicate to me your schema on the people table is missing the "type" column name, which will store the class name of the Object and also trigger the STI behavior of Rails.

    STI means that the 'base class' is the People table.

    Sort of but your error indicates that all that is happening is normal ruby inheritance. So you essentially have the I in STI but not the ST part.

    The point of STI isn't just inheritance of a parent class, this is normal ruby Inheritance, the point is multiple classes using a single table in the database because they're essentially the same schema. However it requires the seemingly invisible "type" column name to trigger the Rails convention of STI in the database. Without this its normal ruby inheritance.

    Note: Having gone down this road in the past I'll warn you that this way lies madness. Especially when the table is self referential as you're looking to do here with your mentioning of foreign keys, i.e. foreign keys to the same table.

    Be careful when you get to step #2 because you're setting up an infinite reference possibility (race condition) or at the least Big O lookups if you start calling the associations too eagerly. For example, JSON may build out the associations on employees for each Person. So it will have to call the same table "people" multiple times to build out each employee's employees, i.e. it becomes employees all the way down. This will be slow.

    0 讨论(0)
提交回复
热议问题