I have built a blog application using Ruby on Rails. In the application I have posts and tags. Post has_many :tags and Tag belongs_to :post.
In the /views/posts/index.html view I want to display two things. First is a listing of all posts displayed 'created_at DESC' and then in the side bar I am wanting to reference my Tags table, group records, and display as a link that allows for viewing all posts with that tag.
UPDATE: The issue of duplicate posts being displayed and posts w/o tags not displaying have been fixed. Just trying to figure out now, how to handle the /posts?tag_name=foobar request such that only the posts with that tag are displayed.
UPDATED CODE: The posts are displaying properly, no duplication. The tag count is working correctly, and the tag groups are displaying as links and passing the tag_name into /posts?tag_name=new. I just can't get the link to trigger the display of only the posts that have those tags. FYI, the posts are identified in the tag table by post_id.
PostsController
def index
@tag_counts = Tag.count(:group => :tag_name, :order => 'updated_at DESC', :limit => 10)
@posts = Post.all( :order => 'created_at DESC' ).paginate :page => params[:page], :per_page => 4,
:conditions =>开发者_开发百科; (params[:tag_name] ?
{ :tags => {:tag_name => params[:tag_name]} } : {}
)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @posts }
format.json { render :json => @posts }
format.atom
end
end
View
Recently Used Tags
<table>
<% @tag_counts.each do |tag_name, tag_count| %>
<tr>
<td><%= link_to(tag_name, posts_path(:tag_name => tag_name)) %></td>
<td>(<%=tag_count%>)</td>
</tr>
<% end %>
</table>
<br>
<a href="/tags">click to view all tags >></a>
</div>
This screen shot might help (please note it is really ugly as just working on function) as it shows that there is only 1 tag in new but when the URL is hit, still displaying all posts.
(source: squarespace.com)To get all posts:
@posts = Post.all.paginate :page => params[:page], :per_page => 5
To show the post's tags:
<% @posts.each do |post| %>
<% post.tags.each do |tag| %>
<%= tag.tag_name %>
<% end %>
<% end %>
I believe this is what you want.
Edit #1
To show the tags in the side bar:
<% Tags.count(:group=>"tag_name").each_pair do |key, value| %>
<% link_name = Tags.find( key ).tag_name %>(<%= value %>)
<%= your_link %>
<% end %>
This will show all the tags with the number of posts between (
)
. But I don't know how to build your link... Maybe if you give some more info, i don't know... Do you have a search
method?
Anyway... hope it helps you :]
Edit #2
Looking another question you've made and seeing some code, I believe this will solve your problem:
#view
<% Tags.count(:group=>"tag_name").each_pair do |key, value| %>
<% tag_name = Tags.find( key ).tag_name %>
<%= link_to(tag_name+"(#{value})", posts_path(:tag_name => tag_name)) %>
<% end %>
#controller
@posts = Post.all.paginate :page => params[:page], :per_page => 5,
:conditions => (params[:tag_name] ?
{ :tags => {:tag_name => params[:tag_name]} } : {}
)
Hope it works now.
A join will create a separate entry for every row - and when you've joined posts on tgas, that means the rows have become a sort of Post+Tag meta-object. So you'll get a post-tag for every tag+post there is.
You probably just want to pull out all the posts and just :include => :tags That will mean all posts will appear (regardless of whether there's a tag on it).
Of course, mixing it with the tag-conditions makes it a bit more complicated. You are not likely to find posts with no tags if you're specifically looking for posts with tags with a given name...
If there's only likely to be one tag with the given tag-name, perhaps you'd do better to do something like:
@posts = Tag.find_by_tag_name(params[:tag_name]).posts
精彩评论