Aleksandrus
Aleksandrus

Reputation: 1754

Rails - How to deal with multiple association

Let's say I have a model, named Student,

A model named Test (the tests students take at school)

An association model named StudentTest, which says when the particular student has done a particular test, under what circumstances, etc..

A model named Questions, which will be used by the tests

An association model named QuestionTest, which says which questions will be on which tests.

Finally, a model named StudentAnswer, which contains a reference to QuestionTest and a reference to Student.

If I have

st = StudentTest.first

I can do:

st.test.questions_test

to get the test questions assigned to that student.

However, if I want the answers of that student, I cannot do this:

st.test.questions_test.student_answers

Because though it will get the answers that are related to those question_test_id, it will not be related to that student_id alone.

An alternative would be

st.test.question_test.student_answers.where(student_id: st.id).all

or

st.student.student_answers.where(test_id: st.test_id).all

But it seems too redundant have to repeat the variable st just to get it's id.

My question is: is there any association that I can declare to make it possible to retrive the answers as:

st.student_answers

or something like it?

EDIT 1: What I was thinking of the use of relations

I was thinking of something like:

student_test.rb

has_many :questions_test, through: :test
has_many :student_answers, through: [:questions_test, :student]

But of course, this has syntax error. Through would only accept one argument

Upvotes: 1

Views: 41

Answers (1)

Wes Foster
Wes Foster

Reputation: 8900

A basic diagram of how I understand it:

  Questions                Test                Student
           \            /        \            /       \
            QuestionTest          StudentTest          |
                  |                                    |
                  \--------------StudentAnswer--------/

If you start with:

st = StudentTest.first

Then you can get the answer for a specific student like so:

student_answers = st.student.answers_for(st.test)

Your answers_for method would look like this:

# student.rb
has_many :student_answers

def answers_for(test)
  student_answers.where(test: test).all
end

This allows you to pull all the answers from the specified test.

Upvotes: 1

Related Questions