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?
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 !
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).