views:

93

answers:

2

I am retrieving data on individual lines within a report with the following named_scope in my survey_response.rb model:

named_scope :job_responses, lambda{|job_code, survey_code| {:conditions => ["survey_job_id = ? AND survey_id = ?", job_code, survey_code]}}

Checking the log I can see that my SQL query is executed as expected. The query returns a list of individual responses for a job survey including mainly numeric data which I need to perform calculations on. Specifically I need to pass the contents of certain fields to an additional method which gets the Standard Deviation of the data in a specific field however I don't understand how to do this.

The external method is called as:

<%= survey_response.standard_deviation([array here]) %>

Currently in my view for each line within the report I retrieve the data appropriate to that line as follows:

<%  r = SurveyResponse.job_responses(survey_response.id, survey_response.survey_id) %>

My question is therefore how do I send the results of a specific field from the returned named_scope data, for example :base_pay, on to my function?

I have tried various different ways but I don't know the syntax to isolate the appropriate field.

+1  A: 

This sort of behavior would probably be better placed in your controller. Anyway, it sounds like all you need to do is collect the values of the field. You could define the data like this:

@job_responses = SurveyResponse.job_responses(survey_response.id, survey_response.survey_id)
@base_pay = @job_responses.collect {|response| response.base_pay}
Chuck
Thanks for the feedback. I figured it should be in the controller but I can't work out how.I am already looping through multiple results in the model from a find on SurveyResponses to find which jobs exist in the survey - so this has to be 'inside' that loop.I don't really understand how I can do a find using the results of an existing find.
+1  A: 

Your core question, about how to get the data back for a specific field, is handled like so:

response = SurveyResponse.job_responses(a,b).first
response.base_pay

I'm guessing from your comments that you would benefit from breaking up your named_scope declaration -- in fact, you don't really need a named_scope to do this. Rails supplies the magic find_all_by_x_and_y method.

Let's say you want to loop over all your surveys and pull out all the job codes in each one. Your code could be like so:

def base_pay_by_survey_and_job
  surveys = Survey.all
  pay_grades = {}
  surveys.each do |survey|
    responses = SurveyResponse.find_all_by_survey_id(survey.id)
    jobs_included = responses.map { |sr| sr.survey_job_id }.uniq
    pay_grades[survey.id] = jobs_included.inject({}) do |pay_by_job, job_code|
      job_responses = responses.select { |sr| jobs_included.include?( sr.survey_job_id ) }
       pay_by_job[job_code] = job_responses.map { |jr| jr.base_pay }
       pay_by_job

    end
  end
  pay_grades
end

There are definitely ways to better optimize this code, but it's fast enough and should be easy to understand. You can put it in a helper, and then reference it from the view. For example if you want to run your function comparing a single respondent against all others with the same job code in the same survey, you could do this:

<% pay_grades = base_pay_by_survey_and_job %>
<%= survey_response.standard_deviation( pay_grades[survey_response.survey_id][survey_response.survey_job_id]) %>
austinfromboston