0
votes

I am new to rails and trying to limit the number of comments displayed on my Posts Index Page to 2.

Below is my posts_controller:

class PostsController < ApplicationController

  before_filter :authorize, :except => [:index, :show]

  # GET /posts
  # GET /posts.xml
  def index
    @posts = Post.all(:include => :comments, :order => "created_at DESC")
    @comments = Comment.find(:all, :order => "created_at DESC", :limit => 1)

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @posts }
    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 # new.html.erb
      format.xml  { render :xml => @post }
    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
        format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
        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])
        format.html { redirect_to(@post, :notice => 'Post was successfully updated.') }
        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
end

Below is my Post model

class Post < ActiveRecord::Base

has_attached_file :photo, :styles => { :medium => "600x600>", :thumb => "100x100>" }, :storage => :s3, :s3_credentials => "#{RAILS_ROOT}/config/s3.yml", :path => "/:attachment/:id/:style/:filename"

has_many :comments

validates :name, :presence => true validates :title, :presence => true, :length => { :minimum => 5 }

end

Below is my posts index view

<table>
  <tr>
     <th>BoxScore</th>
   <th>Content</th>
  </tr>
</table>

<% @posts.each do |post| %>
    <%= image_tag post.photo.url(:medium), :class =>"floatleft" %>
    <p>
  <%= post.content %>
    </p>
    <div class="comments center">
    <h3>Comments:</h3>
        <%= render :partial => post.comments.reverse %>
   <div class="links">
    <% if admin? %>
        <%= link_to "New Post", new_post_path %>
        <%= link_to 'Edit', edit_post_path(post) %>
    <%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %>
    <% end %>
    <%= link_to 'Comment on the Game', post %>
    </div>
</div>
<% end %>

</div>

Comments Partial Below

<% div_for comment do %>
    <p>
        <strong>Posted <%= time_ago_in_words(comment.created_at) %> ago
        </strong>
                by
                <br/>
                <%= h(comment.commenter) %>
                <br/>
        <%= h(comment.body) %>
                <br/>
                <%= link_to 'More Comments', comment.post %>
    </p>
<% end %>

I am not getting an error message, I just don't know how to limit the amount of comments we are rendering on Posts index page. Thanks

1
You should post the content of your partial too thats related to comments and say what kind of error are you getting with this.Kleber S.

1 Answers

1
votes

You can't specify conditions on eager loaded associations, unfortunately. Likewise, you can't limit the number of rows returned based on a condition (to my knowledge, though there are a lot of things I don't know about SQL functions).

So you're stuck with either:

  1. Load all of the comments for the posts you're displaying in a query, and limit the number shown in your application.
  2. Load only 2 comments for each of the posts you're displaying individually.

The optimal solution depends on your use case. If you're expecting to show only 5 posts and have thousands of comments on each, option 1 might not be very performant and option 2 might be a good solution. If you are expecting to show more posts per page and have only a handful of comments on any one (the more likely scenario), the first option is going to be your best bet.

Option 1

# controller
@posts = Post.limit(20).all
@comments = Comment.find(@posts.collect &:id).group_by &:post_id

# view
<% @comments[@post.id].first(2).each do |comment| %>
  ...
<% end %>

Option 2

# controller
@posts = Post.limit(5).all

# view
<% post.comments.limit(2).each do |comment| %>