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

関心のあるすべてのID()でselect *すでに実行されている場合、同じIDのそれぞれに対して別のIDが再度実行されるのはなぜですか?各IDのすべての列をまだ知っていませんか?ROSTER_INFOIN (...)select *ActiveRecordROSTER_INFO

(その間、に対する個別のクエリはありませんが、メソッドからROSTER_CONTACT削除すると、再度クエリされることはありませんが、クエリされます。):roster_contactincludesROSTER_INFOROSTER_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
4

3 に答える 3

1

この問題は関連していることが判明しましたm.roster_contact.member_name- 残念ながら、私はそれ自体 (間接的に) queryedmember_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
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。おそらく、そのうちの 1 つを に変更しbelongs_toます。他の双方向のhas_one関連付けについても同じことを行います。

もう 1 つのことは、foreign_key 列に 'ID' を使用していることです。ここでは、通常の慣行roster_contact_idまたは参照しているクラスに関係ありません。

編集:

よく調べてみると、RosterInfo、 、 、 、 、 、 、単一のレコードであるべきものの別々のテーブルのようRosterContactに見えます。それらはすべて同じ相互関連のセットを持っているからです。これはスキーマ レベルで対処する必要がありますが、現時点では、3 つのモデルのいずれかから関連付けを削除して、差し迫った問題を解決できるはずです。RosterWebhas_onehas_one

ここに画像の説明を入力

于 2012-10-31T16:18:37.553 に答える
0

私は首を突き出して、これはおそらくクエリ エンジンによる実行中の最適化であると言います。'IN' は通常、キーの大きなセットを比較するために使用されます。3 つのキーを解決する最も効率的な方法 (ID がキーであると仮定) は、キーごとに各行を取得することです。

于 2012-10-31T10:29:23.927 に答える