问题
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
回答1:
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
回答2:
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.
回答3:
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
来源:https://stackoverflow.com/questions/29414349/links-to-change-ordering-of-a-posts-loop