stoerebink stoerebink - 9 months ago 33
Ruby Question

Best way to conditionally chain scopes

I'm trying to extend the functionality of my serverside datatable. I pass some extra filters to my controller / datatable, which I use to filter results. Currently in my model I am testing whether the params are present or not before applying my scopes, but I'm not convinced this is the best way since I will have a lot of if/else scenario's when my list of filters grows. How can I do this the 'rails way'?

if params[:store_id].present? && params[:status].present?[:store_id]).status(params[:status])
elsif params[:store_id].present? && !params[:status].present?[:store_id])
elsif !params[:store_id].present? && params[:status].present?


Since relations are chainable, it's often helpful to "build up" your search query. The exact pattern for doing that varies widely, and I'd caution against over-engineering anything, but using plain-old Ruby objects (POROs) to build up a query is common in most of the large Rails codebases I've worked in. In your case, you could probably get away with just simplifying your logic like so:

relation = Order.join(:store)

if params[:store_id]
  relation =[:store_id])

if params[:status]
  relation = relation.status(params[:status])

@orders = relation.all

Rails even provides ways to "undo" logic that has been chained previously, in case your needs get particularly complex.