rails上的下一个对象问题

video表

id title votes_count 

video控制器

 def show @video = Video.find(params[:id]) @next_video = Video.order("votes_count DESC").where("votes_count  ?", @video.votes_count).first end 

问题是有些video具有相同的votes_count数。 当我更改votes_count <to votes_count <=时,它开始在两个视频之间循环。 有任何想法吗? 谢谢。

解决此问题的主要关键是您需要显式包含辅助排序字段,这将使您确定解决具有相同votes_count的行的问题。 您还需要将>=拆分为两个单独的子句,因为您只想在主要=时评估辅助字段。

现在,对于奖励积分,我还要将您的代码重构为模型上的方法,因此您的控制器就变得……

 def show @video = Video.find params[:id] end 

而你的模型变成……

 def next self.class. order( "votes_count, id" ). where( "votes_count > :votes_count OR ( votes_count = :votes_count AND id > :id )", attributes.symbolize_keys ).first end def previous self.class. order( "votes_count DESC, id DESC" ). where( "votes_count < :votes_count OR ( votes_count = :votes_count AND id < :id )", attributes.symbolize_keys ).first end 

现在在您看来,您可以参考@video.next@video.previous

让我们在你的Video模型中添加一些新东西:

 class Video < ActiveRecord::Base def next(column = 'votes_count', order = 'DESC') pos = self.position(column, order) on_position(pos - 1, column, order) if pos > 0 end def previous(column = 'votes_count', order = 'DESC') pos = self.position(column, order) on_position(pos + 1, column, order) end private def position(column, order) order_by = "#{column} #{order}" arrow = order.capitalize == "ASC" ? "<=" : "=>" Video.where("#{column} #{arrow} (?)", self.send(column)).order(order_by).count end def on_position(pos, column, order) order_by = "#{column} #{order}" arrow = order.capitalize == "ASC" ? "<=" : "=>" Video.order(order_by).offset(pos).first end end 

和你的控制器

 def show @video = Video.find(params[:id]) @next_video = @video.next @previous_video = @video.previous end 

注意,我没有测试它,所以它可能是错误的。 所有错误都放在评论中:)

您需要阻止它返回相同的video

 @next_video = Video.order("votes_count DESC").where("votes_count < ? AND id !=", @video.votes_count, @video.id).first 

您还应该添加二级排序(可能通过id或created_at),以便在投票数相等时订单是一致的。