Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reverse order of display of blog entries and comments, Ruby on Rails

I am new to rails so could use some help here. I have followed several tutorials to create a blog with comments and even some of the AJAX bells and whistles and I am stuck on something that I hope is easy. The default display for both blogs and comments is to list the oldest first. How do I reverse that to show the most recent entries and the most recent comments at the top. Don't really know if this is a function of the controller or model. I have done some customization so here is the code for the controller .rb files if it helps.

COMMENTS CONTROLLER

class CommentsController < ApplicationController
  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.create!(params[:comment])

    respond_to do |format|
      format.html { redirect_to @post}
      format.js
    end
  end
end

POSTS CONTROLLER

class PostsController < ApplicationController
  before_filter :authenticate, :except => [:index, :show]

  # GET /posts
  # GET /posts.xml
  def index
    @posts = Post.all(:include => :comments)


    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @posts }
      format.json { render :json => @posts }
      format.atom
    end
  end

  # GET /posts/1
  # GET /posts/1.xml
  def show
    @post = Post.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @post }
    end
  end

  # GET /posts/new
  # GET /posts/new.xml
  def new
    @post = Post.new

    respond_to do |format|
      format.html { redirect_to @post}
      format.js
    end
  end

  # GET /posts/1/edit
  def edit
    @post = Post.find(params[:id])
  end

  # POST /posts
  # POST /posts.xml
  def create
    @post = Post.new(params[:post])

    respond_to do |format|
      if @post.save
        flash[:notice] = 'Post was successfully created.'
        format.html { redirect_to(@post) }
        format.xml  { render :xml => @post, :status => :created, :location => @post }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @post.errors, :status => :unprocessable_entity }
      end
    end
  end

  # PUT /posts/1
  # PUT /posts/1.xml
  def update
    @post = Post.find(params[:id])

    respond_to do |format|
      if @post.update_attributes(params[:post])
        flash[:notice] = 'Post was successfully updated.'
        format.html { redirect_to(@post) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @post.errors, :status => :unprocessable_entity }
      end
    end
  end

  # DELETE /posts/1
  # DELETE /posts/1.xml
  def destroy
    @post = Post.find(params[:id])
    @post.destroy

    respond_to do |format|
      format.html { redirect_to(posts_url) }
      format.xml  { head :ok }
    end
  end

  private

  def authenticate
    authenticate_or_request_with_http_basic do |name, password|
      name == "admin" && password == "secret"
    end
  end
end
like image 938
bgadoci Avatar asked Nov 18 '09 02:11

bgadoci


3 Answers

As jtbandes pointed out, to reverse the posts in the index, you'd change the line in your index action to read:

@posts = Post.all(:include => :comments, :order => "created_at DESC")

In order to reverse the listing of your comments, there are two possibilities.

Option 1: In your post model you can declare your relationship like so:

class Post < ActiveRecord::Base
  has_many :comments, :order => "created_at DESC"
end

Option 2: In your index view, simply reverse the array of each post's comments before displaying them:

<% @posts.each do |post| %>
  <%= render :partial => post %>
  <%= render :partial => post.comments.reverse %>
<% end %>

The options have different use cases. In option 1, you're saying that throughout your entire application, any time you refer to the comments on a post, those comments should be retrieved from the database in the specified order. You're sort of saying that this is an intrinsic property of comments in your application - posts have many comments, which are by default ordered newest first.

In option 2, you're simply reversing the comments in the index page before they're rendered. They were still retrieved in the original order (oldest first) from the database, and they'll still appear in that order anywhere else you access the comments of a post in your application.

like image 158
PreciousBodilyFluids Avatar answered Nov 05 '22 06:11

PreciousBodilyFluids


If you're looking for a more generic way to reverse the order of the .each method, Rails has the .reverse_each method. Like so:

<% @posts.reverse_each do |post| %>
  <%= render :partial => post %>
  <%= render :partial => post.comments.reverse %>
<% end %>
like image 7
Archonic Avatar answered Nov 05 '22 06:11

Archonic


@posts = Post.find(:all, :include => :comments, :order  => "published_at DESC")
like image 3
Alex Polkhovsky Avatar answered Nov 05 '22 07:11

Alex Polkhovsky