Q: How to apply select condition on an array that satisfy '&&' condition specified in filters hash? I have an order that contains multiple bookings and I am trying to apply select condition on the bookings that specify certain condition specified in the hash in the following way
{ status: 'confirmed',
  slot: '1 p.m. - 2 p.m.'}

I need to make a generic function that works on bookings for any number of filters that satisfy the conditions.In this case the condition is {slot '1 p.m. - 2 p.m.' and status is confirmed}
I made the following function for this but was not able to give the && conditions from filters
def bookings_of(filters)
  self.bookings.select do  |booking|
   filters.map{ |key, value| booking.send(key) == value }
  end
end

How should I do this?

A: If you really wanted to do this in Ruby you could do:
def bookings_of(filters)
  self.bookings.select do |booking|
    !!filters.map { |key, value| break if booking.send(key) != value }
  end
end

Using break here will bail as soon as one of the filters does not pass and it uses the fact that nil is falsy while an array is truthy.
But you should probally just use .where and do it in the database instead.
In which case you can do it in one call by merging the array of hashes into a single hash:
bookings.where(filters.reduce({}, :merge))


A: While you may be able to apply all your filters by using send on individual objects, you would probably benefit from letting your database do the work by using ActiveRecord's where.
Beware that If these filters come from request parameters you may be opening a security hole in your application by using send or where.
Consider using an allowlist approach, where you build up the final query depending on all the given filters:
def bookings_of(slot:, status:)
  query = bookings
  query = query.where(slot: slot) if slot
  if ["confirmed", "abandonned"].include?(status)
    query = query.where(status: status)
  end
  query
end


A: def bookings_of(filters)
 self.bookings.select do  |booking|
   filters.map{ |key, value| booking.send(key) == value }.inject(:and)
 end
end

