我有以下代码(请注意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
相应地,我在我的日志中看到以下内容(即从ROSTER_INFO … IN(…)中选择*):
SELECT `ROSTER_INFO`.* FROM `ROSTER_INFO` WHERE `ROSTER_INFO`.`ID` IN ('1450','1000','1111')
然后,在上一个查询的IN列表中已经指定的每个ID之后立即从ROSTER_INFO中选择*:
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
如果在所有感兴趣的ID(IN(…))上已经在ROSTER_INFO上完成了select *,为什么对于每个相同的ID再次执行另一个select *? ActiveRecord是否已经知道每个ID的所有ROSTER_INFO列?
(同时,对于ROSTER_CONTACT没有单独的查询,但如果我从includes方法中删除:roster_contact,则不会再次查询ROSTER_INFO,但ROSTER_CONTACT是.)
RosterInfo模型(删节)
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