This strange behavior is due to the lazy evaluation of ActiveRecord areas. It happens that the string
@dropdown_channels = @dropdown_channels.where(:id => channel.id)
It does not send a query to the database until you actually use the @dropdown_channels value, and when you do this, all states are combined into one large query, so you get AND between the conditions.
To force ActiveRecord to be loaded into scope, you can use the all scope or the first scope, for example:
@dropdown_channels = @dropdown_channels.where(:id => channel.id).first
This will force ActiveRecord to compute the query in place, returning the result immediately and not accumulate areas for lazy evaluation.
Another approach may be to accumulate all these channel_ids and get them later in one request, instead of making a request for each of them. This approach is more cost effective with respect to database resources. For this:
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)
source share