Reputation: 698
Project is located at
http://code-dojo.herokuapp.com/
and
https://github.com/TylerSangster/Code-Dojo
I have a resource review site with the following models.
class Resource < ActiveRecord::Base
has_many :reviews
class Review < ActiveRecord::Base
belongs_to :resource
I have added resource sorting by name, created at, and cost. I would also like to sort by the highest reviewed resource.
How can I create a sort by review.score ?
EDIT resource controller
def index
@resources = Resource.where(status: true).includes([:providers, :subjects, :formats, :reviews])
@resources = @resources.tagged_with(params[:tag]) if params[:tag]
@resources = @resources.order(sort_column + " " + sort_direction)
@resources = @resources.paginate(:page => params[:page], :per_page => 10)
respond_with @resources
end
private methods
def sort_column
Resource.column_names.include?(params[:sort]) ? params[:sort] : "name"
end
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
application.rb
def sortable(column, title = nil)
title ||= column.titleize
css_class = column == sort_column ? "current #{sort_direction}" : nil
direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc"
link_to title, {:sort => column, :direction => direction}, {:class => css_class}
end
index.html.erb
<li><div class="btn btn-default"><%= sortable "created_at", "Most Recent" %></div></li>
<li><%= link_to "Highest Rated", resources_path, class:"btn btn-default" %></li>
<li><div class="btn btn-default"><%= sortable "cost" %></div></li>
Upvotes: 1
Views: 571
Reputation: 58324
Since you want to sort a set of resources based upon their review scores, and there are many review scores per resource, then a means of evaluating them needs to be determined. To do this, one could think about what the scores mean and why they would be sorted for the user.
A logical choice might be to sum the review scores of a resource to create an aggregate score for the resource. It would work like this (assuming @resources
is a collection of Resource active records):
@resources.sort_by( &:aggregate_score )
The highest rated would be the last element:
highest_score_resource = @resources.sort_by( &:aggregate_score ).last
In the Resource model, define aggregate_score
:
def aggregate_score
self.reviews.select { |r| r.score }.sum(&:score)
end
If you know the scores are never nil
, then you could do:
def aggregate_score
self.reviews.sum(&:score)
end
If you decide that there's some other means you want to use to compute an aggregate score for the resource, you change the algorithm in aggregate_score
.
Upvotes: 2
Reputation: 5376
You obviously need order method of ActiveRecord class
Review.order("score")
There is an article that might help you too.
Hope this helps :)
EDIT:
class Resource < ActiveRecord::Base
scope :ordered, :order => "some_col DESC"
end
class Review < ActiveRecord::Base
has_many :resources
end
review.resources # uses the default ordering
review.resources.ordered # uses the "some_col DESC" ordering
Upvotes: 0