我希望能够根据对我的帖子进行排序
- 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提供的一个特殊范围,它选择两个特殊计算的地理空间列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
)
如果您想选择距离但不使用它进行排序,请使用.reorder
,它将替换查询的order子句:
Post.near(user.to_coordinates)
.reorder(
created_at: :asc,
vote_count: :desc
)
选项1:使用演示者对象。为每个帖子创建一个演示者,让演示者计算距离并将其存储在自己中,对演示者而不是帖子进行排序,呈现演示者。
选项2:在地图中存储从post-ids到距离的距离。渲染帖子时,请在帖子id距离图中查找相应的距离。