I'm not experinced with Ruby associations, but it seems to me that somehow data model is cofused with run-time logic here.
If I'd make a data model for question and tests, I'd want to re-use my questions across tests and also re-use prepared tests (sets of questions) across lectures. In that case I'd write something like
class Lecture
has_and_belongs_to_many :tests
end
class Test
has_and_belongs_to_many :lectures
has_and_belongs_to_many :questions
end
class Question
has_and_belongs_to_many :tests
end
Separately from that structure I'd have some structure corresponding to real-time lectures, tests, questions and a notion of a result. A result is an attempt to answer a real-time question by a given student.
I'd also "delegate" the check of the lecture session state to the test session. If test session cannot be started for whatever reason the question session cannot be started too.
To unit-test a question session you will only need to mock a test session, to unit test a test session you will need to mock a lecture session, and so on.
class Lecture_Session
has_many :tests_sessions
belongs_to :lecture
end
class Test_Session
belongs_to :lecture_session
belongs_to :test
has_many :question_sessions
def validate
raise "Lecture not started!" unless lecture_session.started?
end
end
class Question_Session
belongs_to :question
belongs_to :test_session
def validate
raise "Test not started!" unless test_session.started?
end
end
class Result
belongs_to :lecture_session
belongs_to :test_session
belongs_to :question_session
belongs_to :student
def validate
raise "Question is not active!" unless question_session.active?
end
end
Hope this helps.