sort_by 哈希中的多个属性

sort_by multiple attributes in hash

我希望能够根据

对我的帖子进行排序

到目前为止,我已经能够按距离排序,但我无法弄清楚如何构建我的地图,并且仍然能够让数组中的用户看到 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

我的view.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%>

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

选项 1:使用 presenter object。为每个 post 创建一个演示者,让演示者计算距离并将其存储在自身中,对演示者而不是 post 进行排序,渲染演示者。

选项 2:在映射中存储从 post id 到距离的距离。渲染post时,在postid-distance地图中查找相应的距离。

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

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

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

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

.near 是由 Geocoder gem 提供的特殊范围,其中 select 有两个特殊的计算地理空间列 - 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
    )

如果您想 select 距离但不将其用于排序,请使用 .reorder 替换查询的顺序子句:

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