(Dreaded) STI, belongs_to

Having problems with STI. Names below have been changed to protect the innocent. Imagine a system that allows someone to apply for one of two different types of school scholarships. Each scholarship goes through a different review process, represented by a state machine (this is not a state machine question). So there are two state machine classes that differ slightly and subclass a generic StateMachine:

class ScholarshipApplication   belongs_to :state_machine end

class StateMachine end

class StateA < StateMachine   has_one :application end

class StateB < StateMachine   has_one :application end

The problem is I can get a ScholarshipApplication instance to tell me its StateMachine, but the StateMachine can't tell me it's ScholarshipApplication. E.g.:

app = ScholarshipApplication.create state = StateA.create app.state_machine = state app.save app.state_machine # returns what it should sm = app.state_machine sm.scholarship_application # throws error: "Unknown column scholarship_applications.state_a_id..."

So obviously I understand why this fails, since I don't have a state_a_id column in scholarship_applications. I just don't understand whether what I'm doing is achievable and if so, what magic configuration makes it all work. E.g. should my has_one statements be in the superclass? Should I reverse the has_one and belongs_to? Something else?

Thanks!

Gaudi Mi wrote:

Having problems with STI. Names below have been changed to protect the innocent. Imagine a system that allows someone to apply for one of two different types of school scholarships. Each scholarship goes through a different review process, represented by a state machine (this is not a state machine question). So there are two state machine classes that differ slightly and subclass a generic StateMachine:

class ScholarshipApplication   belongs_to :state_machine end

class StateMachine end

class StateA < StateMachine   has_one :application end

class StateB < StateMachine   has_one :application end

The problem is I can get a ScholarshipApplication instance to tell me its StateMachine, but the StateMachine can't tell me it's ScholarshipApplication.

[...]

Perhaps because you should have your has_one read has_one :scholarship_application !

Best,

Perhaps because you should have your has_one read has_one :scholarship_application !

Sorry I should have stated in the original post that I was typing pseudocode here; the actual code doesn't have this mistake.

Gaudi Mi wrote:

Perhaps because you should have your has_one read has_one :scholarship_application !

Sorry I should have stated in the original post that I was typing pseudocode here; the actual code doesn't have this mistake.

Then you *might* need a polymorphic association. I'm not sure: I tend not to use STI.

Best,

Passing the :foreign_key option to the has_ones will definitely work. You might also try hoisting the has_one into StateMachine (if that makes sense for your models), as it's guessing the foreign key named based on the class where it's declared (*probably* - I've not poked the source to check this).

--Matt Jones