急切加载嵌套对象rails

时间:2017-09-30 14:51:46

标签: ruby-on-rails ruby

我有以下模型

Customer.rb

has_many :appointments
has_many :addresses
has_many :contacts

Address.rb

belongs_to :customer

Contact.rb

belongs_to :customer

Appointment.rb

belongs_to :customer

我已经定义了API来返回如下所示的客户,但有一个额外的属性,即appointment_id。

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

]

以上api的定义方式是我传递 @customers (客户数组及其嵌套对象地址,联系人)。问题是如何编写活动记录查询以返回如此数据。

当前方法:

//我得到了约会ID列表,我应该返回相应的客户数据,如上面的api所示。

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

我想要什么?

我的上述方法在@customers对象中没有appointment_id。我该怎么办?我需要加入桌子吗?    与包括。 ??

3 个答案:

答案 0 :(得分:1)

添加关联定义的反转以避免在预加载期间n + 1

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

# appointment
belongs_to :customer, inverse_of: :appointment

现在您可以从数据库中获取约会并构建JSON

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

customers = appointments.map do |appointment|
  appointment.customer
   .as_json(include: [:contacts, :addresses])
   .merge(appointment_id: appointment.id)
end

render json: { customers: customers }

答案 1 :(得分:0)

这是我能想到的

appointment_ids = Appointment.where(blah blah blah).pluck(:id)
customers = Customer.includes(:addresses, :contacts, :appointments).where(appointments: { id: appointment_ids })

现在你要写

customers.first.appointments您只能获得满足第一个条件的约会。

根据您的说法,每位顾客每天只能预约一次。

所以你可以做customers.first.appointments.first.id

答案 2 :(得分:-1)

在查询中使用select

cust_ids = Appointment.where(等等等等).pluck(:customer_id) @customers = Customer.where(appointment_id:cust_ids).includes(:地址,:联系人).select(" customers。*")