Jonathan
Jonathan

Reputation: 683

Links to change ordering of a posts loop

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

Answers (3)

Mohammad AbuShady
Mohammad AbuShady

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

TomDunning
TomDunning

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

Uday kumar das
Uday kumar das

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

Related Questions