Forum: Ruby on Rails Model has_many 3 degrees separation

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Chad (Guest)
on 2009-03-05 10:22
(Received via mailing list)
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
Peter V. (Guest)
on 2009-03-05 11:14
(Received via mailing list)
On Thu, Mar 5, 2009 at 9:21 AM, Chad <removed_email_address@domain.invalid> 
wrote:
>  has_many :survey_questions
> end
>
> class SurveyQuestions ...
>  belongs_to :survey
>  has_many :survey_answers
> end
>
> class SurveyAnswers ...
>  belongs_to :survey_question
> end

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
Chad (Guest)
on 2009-03-05 11:31
(Received via mailing list)
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?



On Mar 5, 1:13 am, Peter V.
Colin L. (Guest)
on 2009-03-05 11:49
(Received via mailing list)
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.

2009/3/5 Chad <removed_email_address@domain.invalid>
Chad (Guest)
on 2009-03-05 12:37
(Received via mailing list)
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...
Peter V. (Guest)
on 2009-03-05 13:02
(Received via mailing list)
On Thu, Mar 5, 2009 at 10:13 AM, Peter V.
<removed_email_address@domain.invalid> wrote:
> (1) @company.surveys.survey_questions.survey_answers
>
> or
>
> (2) @company.survey_questions.survey_answers
>
> I believe form (1) should certainly work

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

Sorry for the noise it created.

Peter
Colin L. (Guest)
on 2009-03-05 14:00
(Received via mailing list)
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.

2009/3/5 Chad <removed_email_address@domain.invalid>
Wojtek Piekutowski (Guest)
on 2009-03-05 17:34
(Received via mailing list)
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
This topic is locked and can not be replied to.