Limiting Comments on Posts Index in Rails App
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
开发者_JAVA技巧 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
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:
- Load all of the comments for the posts you're displaying in a query, and limit the number shown in your application.
- 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| %>
精彩评论