排序基于has_many关系

时间:2013-09-07 23:28:53

标签: ruby-on-rails ruby sorting

项目位于

http://code-dojo.herokuapp.com/

https://github.com/TylerSangster/Code-Dojo

我有一个资源审核网站,其中包含以下模型。

class Resource < ActiveRecord::Base

  has_many :reviews


class Review < ActiveRecord::Base

  belongs_to :resource

我已按名称添加资源排序,创建时间和成本。我还想按最高审查的资源排序。

如何通过review.score创建排序?

EDIT 资源控制器

  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

私人方法

  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

  • &lt;%= sortable“name”%&gt;
  •   <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>
    

    2 个答案:

    答案 0 :(得分:2)

    由于您希望根据其评论分数对一组资源进行排序,并且每个资源有许多评论分数,因此需要确定评估它们的方法。要做到这一点,人们可以考虑分数的含义以及为用户分类的原因。

    逻辑选择可能是对资源的评论分数求和以创建资源的总分。它会像这样工作(假设@resources是资源活动记录的集合):

    @resources.sort_by( &:aggregate_score )
    

    评分最高的是最后一个元素:

    highest_score_resource = @resources.sort_by( &:aggregate_score ).last
    

    在资源模型中,定义aggregate_score

    def aggregate_score
      self.reviews.select { |r| r.score }.sum(&:score)
    end
    

    如果您知道分数永远不会是nil,那么您可以这样做:

    def aggregate_score
      self.reviews.sum(&:score)
    end
    

    如果您决定使用其他方法来计算资源的总分,则可以在aggregate_score中更改算法。

    答案 1 :(得分:0)

    你显然需要ActiveRecord类的订购方法

    Review.order("score")
    

    还有一个article可能对您有帮助。

    希望这会有所帮助:)

    修改

    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