Home > Software engineering >  Rails query returns array instead of ActiveRecord
Rails query returns array instead of ActiveRecord

Time:01-01

I have this query

documents = Broker.find(12).clients.left_joins(:documents).select("clients.id, count(documents.expiration) FILTER (WHERE documents.expiration < '#{Date.today}') AS expired").group("1")

And it returns me a table like this:

id expired
1 4
2 3
5 1
6 2

And I want to add an order after the query. For example:

documents.order("expired")

But I got this error:

NoMethodError (undefined method `order' for []:array)

What can I do to get an ActiveRecord instead of an Array?

CodePudding user response:

It's because of .group invocation at the end of the expression. Documentation says:

Returns an array with distinct records based on the group attribute

So, in order to get an activerecord relation you should eliminate usage of .group.

CodePudding user response:

It looks like the documents variable is an array and not an ActiveRecord relation, which means that it does not have an order method.

To add an order clause to the query, you can modify the select method like this:

documents = Broker.find(12).clients.left_joins(:documents).select("clients.id, count(documents.expiration) FILTER (WHERE documents.expiration < '#{Date.today}') AS expired").group("1").order(expired: :desc)

This will add an order clause to the end of the query, ordering the results in descending order based on the expired column.

if you want to keep the documents variable as an array, you can use the sort_by method to sort the array in descending order based on the expired column:

documents = documents.sort_by { |doc| doc.expired }.reverse

This will sort the documents array in descending order based on the expired column.

  • Related