Deekor
Deekor

Reputation: 9499

ransack sort by model method that returns an integer

I'm trying to figure out how to sort by a method on my model that returns an integer.

class Business < ActiveRecord::Base

  has_many :questions

  def questions_count
    questions.count
  end
end

I'd like to be able to sort by the questions_count method in my table using ransack.

I have tried <th><%= sort_link @q, :questions_count %></th> with no luck.

Is this even possible? How can I achieve it?

Upvotes: 2

Views: 2297

Answers (2)

hypern
hypern

Reputation: 887

The sort_link helper method can only accept an attribute or the attribute of an association, but if you wish to simple return a count of associated records, this is possible using an existing rails mechanism.

The easiest way to achieve this is by using counter_cache - a way to count the number of objects that belong to an associated model. You'll have to add this to the association in your business model like this:

has_many :questions, counter_cache: true

It also requires a database column in the businesses table called questions_count, however, you can actually customise the name of this (and this is what will enable you to pass the number of questions to the sort_link method).

Once this is set up you should be able to call the sort_link helper method without an issue.

sort_link @q, :questions_count

Find more about counter_cache here.

Alternatively, there is 'another' way to achieve this. You can define a ransacker instead. You can use it to explicitly write a SQL statement that can perform a COUNT function on all associated questions for a business, but I don't think its as convenient a solution as the counter_cache method. Mainly because the SQL statement would redefine/replace the questions_count method functionality.

Find more about ransackers here.

Upvotes: 5

Ronan Lopes
Ronan Lopes

Reputation: 3398

Yes, you can sort using something like @collection.sort_by{|item| item.method_name}. Just replace "@collection" by your set of items and "method_name" by the method you want to sort

Upvotes: 0

Related Questions