SupremeA
SupremeA

Reputation: 1621

Controller method to show all instances of one field no duplicates ruby

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

Answers (1)

engineersmnky
engineersmnky

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

Related Questions