I’ve got a method like this:
def transfers(material, capacity, category, created_at)
transfers_range = Transfer.first.created_at..Transfer.last.created_at if created_at.nil?
Transfer.where(
sender_dispensary_id: id,
status: %i[dispatched released returned],
capacity: capacity,
material: material,
created_at: created_at.nil? ? transfers_range : Time.given_month_range(created_at)
).or(
Transfer.where(
receiver_dispensary_id: id,
status: %i[dispatched released returned],
capacity: capacity,
material_id: material,
created_at: created_at.nil? ? transfers_range : Time.given_month_range(created_at)
)
)
end
It’s working, but is there a way to avoid query for transfer_range
? I mean… If created_at == nil
, then this function should skip created_at
column, like it was not included in query
3
Answers
Yes, the
transfers_range
query can be avoided by breaking your query into multiple lines and adding a condition oncreated_at
presence separately. You can also combine both the OR queries into a single query like this:When
created_at
isnil
thentransfers_range
basically covers all transfers and therefore the condition is pointless and I simple would query bycreated_at
in that case.You can consolidate the created_at query logic so it’s in one place and you don’t have to repeat it.
You also don’t need to repeat the whole where condition twice. You want the equivalent of…
You do that like so:
You can make this even more concise, and hide the details, by putting the logic into a scopes.
And now the query is much simpler.