Model has_many 3 degrees separation

I feel like this should be simple but it's stumping me.

In the following model, is there an easy way to setup my models so that I can make the following call: @company.survey_answers

class Company < ActiveRecord::Base   has_many :surveys   has_many :survey_questions, :through => :surveys end

class Surveys ...   belongs_to :company   has_many :survey_questions end

class SurveyQuestions ...   belongs_to :survey   has_many :survey_answers end

class SurveyAnswers ...   belongs_to :survey_question end

Thanks in advance for any help.

Cheers, Chad

What happens when you try:

(1) @company.surveys.survey_questions.survey_answers

or

(2) @company.survey_questions.survey_answers

I believe form (1) should certainly work after removing the line 'has_many :survey_questions, :through => :surveys'

I am uncertain if form (2) will work (because I am uncertain if has_many :through works that way and no time to test it here)

I don't see how '@company.survey_answers' could work since there is no has_many relationship with the name 'survey_answers' in the Company class. It is only defined in the SurveyQuestions class.

HTH,

Peter

I like the idea, but this is what I get:

@answers = @company.surveys.survey_questions.survey_answers

undefined method `survey_questions' for #<Class:0x203b590>

I feel like the first call, @company.surveys is just returning an array and then I'm trying to call the survey_questions method on that array.

Is there a way to modify that call to get the desired chaining?

As you say @company.surveys returns an array of Surveys, so normally you would have to say @company.surveys[i].survey_questions which will again return an array of questions, and so on. Are you asking for a means to automatically combine all the results obtained by iterating each of the arrays down the chain? I don’t know of a way to do that automatically, without iterating each of the arrays and building a combined list. I would not be in the least surprised to find that Ruby has some magic construct to achieve this however. Maybe this is a challenge to the Ruby geeks to provide the answer by the most concise (and possibly undecipherable) code.

Ya I agree with you - I can manually combine arrays no problem, but then it's a pain to sort and I'm unable to use named_scope's, etc.

There's got to be a clean way...

OK, that was stupid of me to post without testing first.

Sorry for the noise it created.

Peter

If you wanted all the answers for a particular company then you could turn it round and find all the answers where survey_question.survey.company = the_company. But if you followed this route for all companies you would still have the problem of grouping the answers by company which is probably no better.

Maybe the other way around...

class Company   has_many :surveys

  def survey_answers     SurveyAnswer.all(:joins => {:survey_question => {:survey => :company}},                      :conditions => ['companies.id = :company_id', {:company_id => id}])   end end

Greetings, Wojtek