私は最適化しようとしているjankyクエリがあります。私はいくつかのメンバーシップパケットロジックに基づいてユーザーレコードのアクティブレコード結合を返したいと思います。select文にif/elseロジックがあるときにActiveRecordクエリを最適化する
ids = User.joins(:memberships).includes(:memberships).select do |user|
if user.memberships.count <= 1
user.membership_packet_sent_at.blank?
else
user.membership_packet_sent_at.blank? && user.current_membership.created_more_than_30_days_ago?
end
end.uniq.map(&:id)
User.where(id: ids)
私は上記に実行している問題は、私はアクティブなレコード協会の代わりに、配列を返すために選択し使用する方法がわからないので、私は2つのクエリをしなければならないということです。
- selectからactiverecordの関連付けを返すにはどうすればよいですか?
- 選択ブロック内でロジックを整理するためのより良い方法はありますか?
編集:
いくつかのリファクタリングの後、私はメソッドに選択ロジックの一部を移動することができました:
`` `
ids = User.joins(:memberships)
.where(membership_packet_sent_at: nil)
.select(&:current_membership_packet_expired?)
.uniq
.map(&:id)
User.where(id: ids)
` ``
代わりにactiverecordアソシエーションを返す方法の問題に取り組んでいます
これは非常にジャッキーだと言っても過言ではありません。主な最適化エラーの初心者は通常N + 1(反復の中のクエリ)です。これは 'preload'を介して防ぐことができます。 –
@maxple fair point。選択してエイジスのソリューションを読む際にメソッドをクリーンアップした後、それは意味をなさない。ありがとう。 – Huy