8

我有以下代码(注意includes.each):

subscribers = []
mailgroup.mailgroup_members.opted_to_receive_email.includes(:roster_contact, :roster_info).each { |m|
  subscribers << { :EmailAddress => m.roster_contact.member_email,
                   :Name => m.roster_contact.member_name,
                   :CustomFields => [ { :Key => 'gender', 
                                        :Value => m.roster_info.gender.present? ? m.roster_info.gender : 'X' 
                                    } ] 
                  } if m.roster_contact.member_email.present?
}
subscribers

相应地,我在日志中看到以下内容(即select * from ROSTER_INFO ... IN (...)):

SELECT `ROSTER_INFO`.* FROM `ROSTER_INFO` WHERE `ROSTER_INFO`.`ID` IN ('1450', '1000', '1111')

然而,紧随其后的是之前查询列表中select * from ROSTER_INFO已经指定的每个 ID :IN

RosterInfo Load (84.8ms)  SELECT `ROSTER_INFO`.* FROM `ROSTER_INFO` WHERE `ROSTER_INFO`.`ID` = '1450' LIMIT 1
RosterInfo Load (59.2ms)  SELECT `ROSTER_INFO`.* FROM `ROSTER_INFO` WHERE `ROSTER_INFO`.`ID` = '1000' LIMIT 1
RosterInfo Load (56.8ms)  SELECT `ROSTER_INFO`.* FROM `ROSTER_INFO` WHERE `ROSTER_INFO`.`ID` = '1111' LIMIT 1

如果select *已经ROSTER_INFO对所有感兴趣的 ID 进行了IN (...)处理select *(还不ActiveRecord知道ROSTER_INFO每个 ID 的所有列?

(同时,没有单独的查询ROSTER_CONTACT,但是如果我:roster_contactincludes方法中删除,则ROSTER_INFO不会再次查询,而是查询ROSTER_CONTACT。)


名册信息模型(删节)

class RosterInfo < ActiveRecord::Base
  self.primary_key = 'ID'
end

RosterContact 模型(删节)

class RosterContact < ActiveRecord::Base
  self.primary_key = 'ID'

  has_many :mailgroup_members, foreign_key: 'rosterID'
  has_many :mailgroups, through: :mailgroup_members

  has_one :roster_info, foreign_key: 'ID'     # can use this line
  #belongs_to :roster_info, foreign_key: 'ID' # or this with no difference

  def member_name                             # I added this method to this
    roster_info.member_name                   # question only *after* having
  end                                         # figured out the problem.
end

RosterWeb 模型(删节)

class RosterWeb < ActiveRecord::Base
  self.primary_key = 'ID'
end

邮件组模型(删节)

class Mailgroup < ActiveRecord::Base
  self.primary_key = 'ID'

  has_many :mailgroup_members, foreign_key: 'mailCatID'

  has_one :mailing_list, foreign_key: :legacy_id
end

MailgroupMember 模型(删节)

class MailgroupMember < ActiveRecord::Base
  self.primary_key = 'ID'

  belongs_to :mailgroup, foreign_key: 'mailCatID'
  belongs_to :roster_contact, foreign_key: 'rosterID'
  belongs_to :roster_info, foreign_key: 'rosterID'
  belongs_to :roster_web, foreign_key: 'rosterID'

  scope :opted_to_receive_email, joins(:roster_web).where('ROSTER_WEB.receiveEmail=?', 1)
end
4

3 回答 3

1

这个问题原来与m.roster_contact.member_name- 不幸的是我自己(间接)查询了member_name一个方法。我通过更改线路解决了这个问题roster_contactroster_info.member_name

:Name => m.roster_contact.member_name,

直接查询roster_info如下

:Name => m.roster_info.member_name,

我很抱歉给您带来麻烦!

于 2012-10-31T20:26:20.677 回答
0

我要伸出我的脖子说这可能是您的查询引擎正在进行的优化。'IN' 通常用于比较大组键,解决三个键(假设 ID 是键)的最有效方法是按键检索每一行,就像发生的那样。

于 2012-10-31T10:29:23.927 回答
0
class RosterInfo < ActiveRecord::Base
  has_one :roster_contact, foreign_key: 'ID'  
end

class RosterContact < ActiveRecord::Base
  has_one :roster_info, foreign_key: 'ID' 
end

我不知道拥有双向的前提是什么has_one,但我怀疑结果会很糟糕。可能将其中一个更改为belongs_to. 对其他双向has_one关联执行相同的操作。

另一件事是您对 foreign_key 列使用“ID”,通常的做法是roster_contact_id或您引用的任何类。

编辑:

仔细观察,RosterInfo, RosterContact,RosterWeb看起来应该是单个记录的单独表,因为它们都具有相同的相互has_one关联集。这是应该在模式级别解决的问题,但是现在您应该能够从三个模型之一has_one中删除关联来解决您的直接问题。

在此处输入图像描述

于 2012-10-31T16:18:37.553 回答