I want to be able to sort my posts based on
So far I've been able to sort by distance, but I'm having trouble figuring out how to construct my map and still be able to keep distance
visible to my users in the array (even though they have chosen to sort by vote_count
for instance)
User calls update_order from view
def update_order
@order = params[:order]
@posts = Post.all
get_distance_posts
end
The method that determines the distance:
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
My 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%>
Any help would be greatly appreciated!
You should not be doing ordering in Ruby in the first place. You will be pulling all of the records out of the database and your server will start to have serious performance problem and eventually start crashing when your app scales as it will exhaust the available memory.
Instead you want to use .order
which adds an order clause to the query to sort the results.
Post.near([48.848903, 2.354533])
.order(
created_at: :asc,
vote_count: :desc
)
This allows you to apply paging and limits to the query to prevent the above mentioned memory issues.
.near
is a special scope provided by the Geocoder gem which selects two special calculated geospatial columns - distance
and bearing
. It also orders by distance.
Here I'm using a static set of coordinates but you can pass a set of coordinates from your model or even an address that will be geocoded:
# 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
)
If you want to select the distance but not use it for ordering use .reorder
which replaces the order clause of the query:
Post.near(user.to_coordinates)
.reorder(
created_at: :asc,
vote_count: :desc
)