-1

Simple problem I can't figure out.

How do you get a list of associated items that are associated with a list of another type of item. For example a Clinician has_many patients through care_group_assignments and patients has_many assessments. I want a list of patients to give me a list of all of their assessments. @patients gives me the list of patients; how do I get their lists of assessments? I want @assessments to be a list of all of the assessments associated with all of the patients associated with a given clinician.

I have a has_many :through relationship between 'Clinician', and 'Patient' with a joined model 'CareGroupAssignment'.

clinician.rb (simplified)

class Clinician < ActiveRecord::Base
    has_many :patients ,:through=> :care_group_assignments
    has_many :care_group_assignments, :dependent => :destroy
    has_many :assessments, :through => :patients

    belongs_to :user
    accepts_nested_attributes_for :user,  :allow_destroy => true
end

patient.rb

class Patient < ActiveRecord::Base
    has_many :clinicians ,:through=> :care_group_assignments
    has_many :care_group_assignments

    has_many :assessments, dependent: :destroy

    belongs_to :user
    accepts_nested_attributes_for :user,  :allow_destroy => true
end

care_group_assignments.rb

class CareGroupAssignment < ActiveRecord::Base
    belongs_to :clinician
    belongs_to :patient
end

I tried using answers from 4720492, 9408931, and 15256541.

I am trying to get the list in the ClinicianController:

def show
  @clinician = Clinician.find_by(id: params["id"])
  @patients = @clinician.patients
  @assessments = @patients.assessments.order("created_at desc")
end

current_clinician is defined in my ApplicationController as:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  helper_method :current_user
  before_action :require_user
  helper_method :current_clinician
  before_action :require_clinician

  def current_user
    @current_user ||= User.find_by!(auth_token: cookies[:auth_token]) if cookies[:auth_token]
  end

  def require_user
    if current_user.nil?
      redirect_to new_session_path
    end
  end

  def current_clinician
    current_user.clinician
  end

  def require_clinician
    if current_clinician.nil?
      redirect_to new_session_path
    end
  end
end

Right now I get a NoMethodError in CliniciansController#show,

undefined method `assessments' for #Patient:.....

Rails 4.1.8, ruby 2.2.1p85, PostgreSQL

Thanks

Community
  • 1
  • 1
Skiapex
  • 153
  • 3
  • 14
  • Can you describe what do you want to show in `@esas_assessments = @patients.assessments.order("created_at desc")`? – akbarbin Sep 22 '15 at 06:25
  • I want a list of `patients` to give me a list of all of their `assessments`. `@patients` gives me the list of patients; how do I get their lists of `assessments`? I want `@assessments` to be a list of all of the `assessments` associated with all of the `patients` associated with a given `clinician`. – Skiapex Sep 22 '15 at 06:40

3 Answers3

2

Have you tried @clinician.assessments? You should be able to get the results you want through the magic of AR and join tables!

David Meza
  • 3,080
  • 3
  • 16
  • 18
  • that worked! thanks. can't believe it was that simple – Skiapex Sep 22 '15 at 07:07
  • No problem! For future reference, when you have has_many/belongs_to methods, they become part of the model's callable methods. For example, for any clinician you can call the following methods in addition to the clinician's attributes: clinician.patients, clinician.care_group_assignments, clinician.assessments, and clinician.user. Active Record does all the heavy lifting (generating the SQL queries) for you! – David Meza Sep 22 '15 at 07:16
0

According your Patient model, Patient has_many assessments but in action show you use:

@assessments = @patients.assessments.order("created_at desc")

Where @patients - list of items of the model Patient.

You should refactor you logic there.

Skiapex
  • 153
  • 3
  • 14
Alexander Shlenchack
  • 3,779
  • 6
  • 32
  • 46
  • How do you recommend I refactor my logic? I want a list of items to give me a list of all of their sub-items. `@patients` gives me the list of patients; how do I get their lists of `assessments`? – Skiapex Sep 22 '15 at 06:31
  • As minimum you should use joins, like in the next answer. – Alexander Shlenchack Sep 22 '15 at 07:01
0

Try to do this:

 @assessments = Assessment.joins(:patient => {:care_group_assignments => :clinician).where(["clinicians.id = ?", @clinician.id]).order("assessments.created_at desc")

I hope this help you.

akbarbin
  • 4,985
  • 1
  • 28
  • 31
  • returns **ActiveRecord::ConfigurationError in Pages#home** `Association named 'clinician' was not found on Patient; perhaps you misspelled it?` – Skiapex Sep 22 '15 at 07:04