この奇妙な振る舞いは、ActiveRecordによるスコープの遅延評価によるものです。何が起こるかというと
@dropdown_channels = @dropdown_channels.where(:id => channel.id)
の値を実際に使用するまでDBにクエリを送信しません。実際に使用する@dropdown_channels
と、すべての条件が1つの大きなクエリに連結されます。これが、条件間にANDを取得する理由です。
ActiveRecordにスコープのロードを強制するために、all
スコープまたはスコープのいずれかを使用できますfirst
。次に例を示します。
@dropdown_channels = @dropdown_channels.where(:id => channel.id).first
これにより、ActiveRecordはその場でクエリを計算し、結果をすぐに返し、遅延評価のスコープを蓄積しません。
別のアプローチは、それらすべてのchannels_idを累積し、それぞれに対してクエリを作成するのではなく、後で1つのクエリで取得することです。このアプローチは、DBリソースに関してより費用効果があります。これを達成するために:
dropdown_channels_ids = []
@channels.each do |channel|
unless @guide_channels.where(:id => channel.id).exists?
dropdown_channels_ids << channel.id
end
end
@dropdown_channels = @dropdown_channels.where(:id => dropdown_channels_ids)