krishnar krishnar - 3 years ago 140
Ruby Question

eager loading nested object rails

I have models like below


has_many :appointments
has_many :addresses
has_many :contacts


belongs_to :customer


belongs_to :customer


belongs_to :customer

I have defined API's to return customers like below but with one extra attribute i.e appointment_id.

customers: [
appointment_id: 'xxxxxxx'
addresses: [{...}, {...}]
contacts: [{...},{...}]


The above api is defined in a way that I pass @customers (which is array of customers along with their nested objects address, contacts). Problem is How should write active record query to return so so data.

Current Approach:

// I got list of appointment id's and I should return corresponding customers data as shown in above api.

cust_ids = Appointment.where(blah blah blah).pluck(:customer_id)
@customers = Customer.where(appointment_id: cust_ids).includes(:addresses, :contacts)

What I want?

My above approach doesnt have appointment_id in @customers object. How should I get it? Do I need to join table
along with includes. ??

Answer Source

Add inverse of to association definitions to avoid n+1 during preload

# customer.rb
has_many :appointments, inverse_of: :customer

# appointment
belongs_to :customer, inverse_of: :appointment

Now you can fetch your appointments from the DB and construct JSON

# in the controller
appointments = Appointment.where(blah blah blah)
  .preload(customer: [:contacts, :addresses])

customers = do |appointment|
   .as_json(include: [:contacts, :addresses])

render json: { customers: customers }
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download