这种奇怪的行为是由于 ActiveRecord 对范围的惰性评估。发生的事情是这条线
@dropdown_channels = @dropdown_channels.where(:id => channel.id)
在您实际使用 的值之前不会向数据库发送查询@dropdown_channels
,并且当您这样做时,它将所有条件连接到一个大查询中,这就是您在条件之间获得 AND 的原因。
为了强制 ActiveRecord 预先加载范围,您可以使用all
范围或first
范围,例如:
@dropdown_channels = @dropdown_channels.where(:id => channel.id).first
这将强制 ActiveRecord 立即计算返回结果的现场查询,而不是累积延迟评估的范围。
另一种方法可能是累积所有这些 channels_id 并稍后在一个查询中获取它们,而不是为每个查询。这种方法与数据库资源相关的成本效益更高。为了实现这一点:
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)