Rails - 更改关系选择

时间:2014-10-01 17:21:07

标签: ruby-on-rails activerecord

我有以下关系:

class Complaint < ActiveRecord::Base
  belongs_to :contact
  has_one :address, as: :addressable, dependent: :destroy
end

class Contact < ActiveRecord::Base
  has_many :complaints
  has_many :personal_addresses, -> { where type: 'personal' }, as: :addressable, class_name: "Address", dependent: :destroy
end

当投诉有联系人时,我需要使用联系人发送的第一个personal_address,如果没有,我需要使用投诉地址。

我已经有了它,但现在数据开始增长,事情变得缓慢。所以我需要选择所有的投诉并在同一个sql中包含地址。

为此,我使用以下内容重载了投诉中的地址方法:

if self.use_contact_address && !self.contact_id.nil?
    Address.where(addressable_type: 'Contact').where(addressable_id: self.contact_id).where(type: 'personal').first
else
    read_attribute(:address)
end

这个问题是自定义选择返回一个数组。我改变了返回数组的第一个元素,但是这个rails已经为每个元素做了一个选择。

有人知道如何重载地址方法以使rails能够执行单个select以从DB返回所有地址吗?

我需要什么:加载来自数据库的所有投诉,并以AR查询一起加载地址的方式进行。但如果投诉使用联系地址,我需要AR知道它需要使用不同的查询加载地址。

我需要做的查询如下:Complaint.all.includes(:address)

感谢并抱歉英语不好。

3 个答案:

答案 0 :(得分:0)

如果

class Contact
  def address
    personal_addresses.first.presense || complaints.first.address
  end
end

答案 1 :(得分:0)

@contact.complaints.all 

这将执行一次选择以获取与您的联系人实例相关的所有投诉。不确定这是否会解决您的问题,因为描述有点不清楚。

答案 2 :(得分:0)

complaints=Complaint.includes(:address, {contact: :personal_addresses}).all

complaints.first.contact.personal_adresses.first 

在访问地址和contact.personal_adresses关系时,它不应针对任何投诉成员触发其他查询