sort_by 哈希中的多个属性
sort_by multiple attributes in hash
我希望能够根据
对我的帖子进行排序
- created_at asc(包括距离)
- vote_count desc(包括距离)
- 距离递增
到目前为止,我已经能够按距离排序,但我无法弄清楚如何构建我的地图,并且仍然能够让数组中的用户看到 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 有两个特殊的计算地理空间列 - distance
和 bearing
。它还按距离排序。
这里我使用的是一组静态坐标,但您可以从您的模型中传递一组坐标,甚至可以传递一个将被地理编码的地址:
# 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
)
我希望能够根据
对我的帖子进行排序- created_at asc(包括距离)
- vote_count desc(包括距离)
- 距离递增
到目前为止,我已经能够按距离排序,但我无法弄清楚如何构建我的地图,并且仍然能够让数组中的用户看到 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 有两个特殊的计算地理空间列 - distance
和 bearing
。它还按距离排序。
这里我使用的是一组静态坐标,但您可以从您的模型中传递一组坐标,甚至可以传递一个将被地理编码的地址:
# 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
)