cm1745
cm1745

Reputation: 140

Rails 5 using Ransack, custom scope order for sorting

I'm using Rails 5 with Ransack, and I have a Model with a column in my Mysql db called status. Status is an integer from 0-5. I am trying to create a default ordering on this column where it is ascending, with the exception of status's that are 0 being last (1, 2, 3, 4, 5, 0).

I am able to get the objects in ascending order without the objects where status == 0 with:

  scope :asc_no_approved, lambda { where.not(status: [0]).order('status ASC') }

And the objects where status == 0 with:

  scope :approved, lambda { where(status: [0]) }

Is there a way to append this second scope to the end of the first? I tried:

scope :asc_approved_last, lambda { where.not(status: [0]).order('status ASC').where(status: [0]) }

But that returns no objects with the following Mysql:

SELECT  `requests`.* FROM `requests` WHERE (`requests`.`status` != 0) AND `requests`.`status` = 0 ORDER BY status ASC LIMIT 10 OFFSET 0

UPDATE:

Since the comments below are somewhat confusing, if anyone else is trying to solve this, this is what worked for me. As per the accepted answer, these are my scopes:

scope :asc_no_approved, lambda { where.not(status: [0]).order('status ASC') }
scope :approved, lambda { where(status: [0]) }
scope :asc_approved_last, lambda { asc_no_approved + approved }

And here is my call in the controller:

@requests = Kaminari.paginate_array(@q.result.includes(:employee, :user, :title).asc_approved_last).limit(10).page(params[:page])

Upvotes: 0

Views: 1625

Answers (1)

Tom Finney
Tom Finney

Reputation: 2918

You can chain scopes together like that fine, you could even just do asc_no_approved.approved but I think the reason it is returning zero objects is because you are looking for all things where the status is not 0, and then asking for the things of this collection where the status is 0.

WHERE (`requests`.`status` != 0) AND `requests`.`status` = 0

If you want to literally append the results of approved to asc_no_approved then you could just do approved + asc_no_approved

Upvotes: 2

Related Questions