Reputation: 3527
I've got a controller method that sorts elements by a derived attribute. I can print to the view as long as I don't attempt to paginate. When I call @foos = @foos.page params[:page]
I get the following error: undefined method 'page' for #<Array:...>
Can anyone provide some guidance here? Thanks.
Here's the whole controller method:
def index_by_capacity
if current_user.is_view_major?
@foos = Foo.major_attr(:name)
else
@foos = Foo.order(:name)
end
@foos = @foos.sort_by! {|a| a.capacity_available.to_i }
@total_foos = @foos.count
@foos = @foos.page params[:page]
respond_to do |format|
format.html
format.json { render json: @foos }
end
end
Upvotes: 4
Views: 1027
Reputation: 54882
The .sort_by!
method returns an Array, which has no method page
(a ruby Array can't be paginated, you would have to implement it yourself or use an external lib).
The pagination works on ActiveRecord::Relation objects, returned by queries like .where
or .order
In you case, you should do an order at the DB-level (faster than doing a sort via Ruby):
@foos.order(:capacity_available)
If the capacity_available
attribute is a String (not an Integer), you can CAST it as an INT:
@foos.order('CAST(capacity_available AS INT) ASC')
(You may need to edit the CAST()
function, it should work on PostGreSQL, not sure about MySQL)
Upvotes: 5
Reputation: 5721
If you want to continue using an array instead of an active record relation object, you can simply include WillPaginate::Collection
.
From WillPaginate Documentation
Previously, all objects returned from paginate methods were of WillPaginate::Collection type. This is no longer true; in Active Record 3, the paginate and page methods return a Relation that is extended to look like a WillPaginate::Collection. Similarly, DataMapper returns a regular DataMapper::Collection that is also extended.
Both ActiveRecord::Relation and DataMapper::Collection are lazy arrays in the way that they don't execute any SQL queries until the point when data is needed. This makes them better than ordinary arrays.
The WillPaginate::Collection class is still available, however, and mostly unchanged.
The Array#paginate method still exists, too, but is not loaded by default. If you need to paginate static arrays, first require it in your code:
require 'will_paginate/array'
Upvotes: 1