Reputation: 1621
I am making a blog and I need to show all the tags associated with a type of user in a list and link to each group of post that has that tag. I want to create a controller method to call in the view to show the list of unique tags. Here are my controller and view. How can I do this?
Controller
def index
@manager_posts = Blog::Post.where(post_type: 'Manager').order('date DESC').limit(4)
@tenant_posts = Blog::Post.where(post_type: 'Tenant').order('date DESC').limit(4)
@blog_list = Blog::Post.order('date DESC').limit(4)
@blog_posts = Blog::Post.paginate(:page => params[:page], :per_page => 5)
@all_post = Blog::Post.all
respond_with(@blog_posts)
end
My view to show the tags currently looks like this
<h3 class="title">Popular Tags</h3>
<div class="separator-2"></div>
<div class="tags-cloud">
<% if @manager_posts.present? %>
<% @manager_posts.each do |post| %>
<% if post.tags.present? %>
<% post.tags.each do |tags| %>
<div class="tag">
<a href= "#"><%= tags %> </a>
</div>
<% end %>
<% end %>
<% end %>
<% end %>
This seems long and unnecessary. Each Post has an array of tags like so...
tags = ["real estate", "property management", "rental"]
I want it to show a list of all tags in all post but only show each instance once and when you click the tag it should show all the post that contain that instance.
Thanks in advance for any help.
Upvotes: 0
Views: 30
Reputation: 29478
You should be able to do something like this
def index
#....
@uniq_tags = @manager_posts.flat_map(&:tags).uniq
end
flat_map
will map the results to a flattened Array so if you have 3 posts having tags ["real estate", "property management"],["rental","real estate"],[]]
then this becomes ["real estate", "property management","rental","real estate"]
and i am sure you can understand what uniq
does.
Then your view becomes
<h3 class="title">Popular Tags</h3>
<div class="separator-2"></div>
<div class="tags-cloud">
<% @uniq_tags.each do |tag| %>
<div class="tag">
<a href= "#" class="post_filter" data-tag='<%= tag %>'><%= tag %> </a>
</div>
<% end %>
</div>
</div>
Edit based on comment: Assuming a post looks like
<% @manager_posts.each do |post| %>
<div class='<%= "post #{post.tags.join(' ')" %>' />
<% end %>
Then this jQuery should work for one tag at a time Example
$(document).ready(function(){
$('.post_filter').on('click',function(event){
var tag = $(this).data("tag")
$('div.' + tag).show();
$('div:not(.' + tag + ')' ).hide();
});
});
If you want multiple tags selected at a time I think it best you try and set that up for your self.
Upvotes: 1