(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