Sort Array in Controller
Hello I'd like to sort an array in a Rails Controller. I want to sort the array before I loop over it in the View
@projects = Project.all.sort #throws error
#and
@projects = Project.all
@projects.开发者_开发知识库sort # throws error
throws this error: undefined method <=>
for #<Project:0x101f70b28>
but when I query:
@projects.respond_to?('sort')
I get true
How can I sort the array? Should it be done in the View or in the Controller? Any help is highly appreciated!
Ruby doesn't know how to sort your project. You must specify the field to use for the sort. Example for created_at
:
@projects = Project.all.sort { |p1, p2| p1.created_at <=> p2.created_at }
or
@projects = Project.all.sort_by &:created_at
Alternatively, you can sort them at database level:
@projects = Project.find(:all, :order => 'created_at')
When you try and sort an array of objects, ruby needs to know how to decide which objects come first.
If your objects have an intrinsic order, e.g. They have a "number" to be sorted by, then implement a method in your Project like this:
def <=> other
number <=> other.number
end
The <=> method is used by ruby to compare two objects and determine which appears first. In this example we just delegate the sorting to the number attribute (strings and numbers both already have a built in order)
The alternative, if there may be many ways to sort your objects, is to specify at sort time how to sort. As True Soft explained there are a few ways to do that, my favourite being
@projects = Project.all.sort_by &:created_at
..to sort by the created_at field
The simplest way is to override <=> in Project:
def <=>(other_project)
self.some_comparable_field <=> other_project.some_comparable_field
# or otherwise return 1, 0 or -1 based on custom comparison rule
end
Then your original code will work.
See: http://ruby-doc.org/core/classes/Comparable.html
精彩评论