I'm building a basic forum application in Ruby on Rails (v4.1.7) and I'm having an issue with displaying the topics in descending order based on their last post. The code I'm using below will show the topics in the correct descending order, however the last post times and last poster name are wrong.
When I view the topic with comments#index, these data are correct. Both comments#index and topics#index call the same partial to display the topic:
I believe this may have to do with me calling topic.comments.last Testing it out, it seems to be displaying the FIRST comments userdata and created_at, rather than the last, however the forums ARE showing up in the correct order.
Partial: _topic.html.erb:
<article class="topic">
<h2><%= link_to(topic.title, topic_comments_path(topic)) %></h2>
<div class="author">
By <strong><%= topic.user.name %> </strong>
on <%= topic.created_at.strftime('%b %d %Y') %>
</div>
<div class="stats">
Viewed <%= pluralize(topic.view_count, 'time') %>.
<% if topic.comments.any? %>
Last comment <%= time_ago_in_words(topic.comments.last.created_at) %> ago
by <%= topic.comments.last.user.name %>.
<% else %>
No comments.
<% end %>
<span class="pull-right">
<%= pluralize(topic.comments.count, 'comment') %>.
</span>
</div>
</article>
topics_controller#index (produces incorrect data):
def index
@topics = Topic.includes(:comments).order('comments.created_at desc')
end
I have also attempted:
def index
@topics = Topic.includes(:comments).paginate(page: params[:page]).order('comments.created_at desc')
end
topics/index.html.erb(wrong data):
<% provide(:title, 'Forum Index') %>
<%= render partial: @topics, spacer_template: 'shared/hr' %>
Viewing a specific thread (in this case the topic.comments.last.user.name and topic.comments.last.created_at are the correct values):
def index
@context = context
@comments = @context.comments.paginate(page: params[:page])
end
#...
private
def context
Topic.find(params[:topic_id]) if params[:topic_id]
end
topics/index.html.erb (right data):
<% provide(:title, @context.title) %>
<h1>View Discussion</h1>
<%= render(partial: 'topics/topic', object: @context) %> # Partial with right data
<hr />
<%= render(partial: 'comment',
collection: @comments,
spacer_template: 'shared/hr',
locals: { topic: @context }) || 'No comments.' %>
<hr />
<%= render partial: 'comment_form', locals: { context: @context,
comment: @context.comments.new } %>
topic.comments.last
should be
topic.comments.first
because you're placing the latest comments first.
Where it's working fine, it is because you aren't ordering the comments and the last
will fetch the comment with the highest primary index value which is most likely the ID.
Hope that clears it up.
And just FYI:
topic.comments.count
will fire up another query in your view. Change the count
to size