Domanda

Currently my data structure includes Appointments, which belong to Contracts. I need to access list of all contracts along with the contracts' appointments (appointments filtered by field_rep).

def index # ContractsController
    rep_name = # …
    render json: Contract.all.map { |c| c.as_json_with_appointments_for_rep(rep_name) }
end

# Contract.rb
def as_json_with_appointments_for_rep(rep_name)
    appts = Appointment.where("contract_id=#{ self.id } AND rep_name='#{ rep_name }'")
    self.as_json.merge({ appointments: appts })
end
def as_json(options = {})
    super(except: [:created_at, :updated_at, :user_id]).merge({ dropoff_date: self.dropoff_date, items: self.active_items, user: self.user })
end

Here, every contract requires a separate database call to get its appointments, resulting in horrible response times.

I'm thinking I'll INNER JOIN appointments and contracts on Appointments.contract_id = Contracts.id but I'm not sure how to bundle the Appointment results into a nested hash in the result. Current output looks like

[ // List of contracts
  {
    'id': 1,
    'appointments': [
      {
        'id': 1,
        // … other appointment fields
      },
      // … More appointments
    ]
  },
  // … More contracts
]

The client is built to handle a contract with no appointments (if a contract has no appointments assigned to the provided rep). Currently using PostgreSQL on Heroku

È stato utile?

Soluzione

Seems like you need to to use an outer join. Rails implements this with includes or eager_load.

In your case you can have

@contracts = Contract.a_desired_scope.includes(:appointments)

then

@contracts.to_json

will only require one query to fetch all contracts with their relevant appointments.

instead of to_json you can use whatever iterating method you want, without affecting the number of queries.

In your case you can have a to_json method for each model

#apointment.rb

def to_json
  desired_attributes_hash.to_json
end

and

#contract.rb

def to_json
  {
   id: id
   apointments: apointments.map(&:to_json)
  }
end
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top