按哈希中的多个属性排序



我希望能够根据对我的帖子进行排序

  • created_at asc(包括距离(
  • vote_count desc(和include distance(
  • 距离asc

到目前为止,我已经能够按距离排序,但我很难弄清楚如何构建我的地图,并且仍然能够让distance对阵列中的用户可见(即使他们选择了按vote_count排序(

用户从视图调用update_order

def update_order
@order = params[:order]
@posts = Post.all
get_distance_posts
end

确定距离的方法:

def get_distance_posts
posts = {}
@posts.map{ |post| posts[post.id] = (check_coordinates_present?(post, current_user) ? get_users_distance(post,current_user) : 0 ) }
@sorted_posts = Hash[*posts.sort_by {|_key, value| value}.flatten]
end

我的视图.html.erb

<% @sorted_posts.map do |u_id, dist|  %>
<% post = @posts.find(u_id) %>
<p> <%= post.created_at %> </p>
<p> <%= post.vote_count %> </p>
<p><%= dist %></p>
<% end%>

如有任何帮助,我们将不胜感激!

您首先不应该在Ruby中进行排序。您将从数据库中提取所有记录,您的服务器将开始出现严重的性能问题,并最终在应用程序扩展时开始崩溃,因为它将耗尽可用内存。

相反,您希望使用.order,它向查询中添加了一个order子句来对结果进行排序。

Post.near([48.848903, 2.354533])
.order(
created_at: :asc, 
vote_count: :desc
)

这允许您对查询应用分页和限制,以防止出现上述内存问题。

.near是Geocoder gem提供的一个特殊范围,它选择两个特殊计算的地理空间列distancebearing。它还按距离排序。

这里我使用的是一组静态坐标,但你可以从你的模型中传递一组坐标,甚至可以传递一个地理编码的地址:

# to_coordinates is provided by Geocoder
Post.near(user.to_coordinates)
.order(
created_at: :asc, 
vote_count: :desc
)
Post.near("Beijing")
.order(
created_at: :asc, 
vote_count: :desc
)

如果您想选择距离但不使用它进行排序,请使用.reorder,它将替换查询的order子句:

Post.near(user.to_coordinates)
.reorder(
created_at: :asc, 
vote_count: :desc
)

选项1:使用演示者对象。为每个帖子创建一个演示者,让演示者计算距离并将其存储在自己中,对演示者而不是帖子进行排序,呈现演示者。

选项2:在地图中存储从post-ids到距离的距离。渲染帖子时,请在帖子id距离图中查找相应的距离。

最新更新