Reputation: 683
I'm trying to achieve links in my page that allow me to change the order that my posts display in. Similar to 'Recent', 'Hot' and 'Oldest' on Reddit.
I currently have by default
PostsController.rb
def index
@posts = Post.order('created_at DESC').all.paginate(page: params[:page], per_page: 20)
end
How would I go about adding links to a method to reverse the flow of posts to ASC or to display posts descending by a specific column on the model like views?
Jon
Upvotes: 0
Views: 501
Reputation: 42799
I'd create some scopes and a method in the model to handle all the possibilities,
# Post.rb
scope :recent, -> { order(created_at: :desc) }
scope :hot, -> { order(something: :desc) }
scope :oldest, -> { order(created_at: :asc) }
def self.sort_by(sort_param)
case sort_param
when 'recent'
recent
when 'hot'
hot
when 'oldest'
oldest
else
all
end
end
# controller
@posts = Post.sort_by(params[:order]).paginate(page: params[:page], per_page: 20)
Since I'm whitelisting, I don't really need to sanitize, any wrong param will return the default order.
If you want you could use #send
and add method names to the whitelist array, but you need to make sure that the scope exists
def self.sort_by(sort_param)
if %w(recent hot oldest).include? sort_param
send sort_param
else
all
end
end
Upvotes: 2
Reputation: 4877
firstly you want to remove the all
so that pagination works better.
def index
@posts = Post.order('created_at DESC').paginate(page: params[:page], per_page: 20)
end
then you can use a variable to control the order. The important thing is to sanitise before passing to mysql.
def index
sort_by = ActiveRecord::Base::sanitize(params.permit(:sort_by))
@posts = Post.order(sort_by).paginate(page: params[:page], per_page: 20)
end
Upvotes: 0
Reputation: 1613
Use will_paginate
gem in your app for Sorting
in both directions and Paginate
.Visit this link to implement it https://github.com/mislav/will_paginate.
Upvotes: 0