Steve
Steve

Reputation: 21

How to display articles from a category in pills form using ruby on rails

I am trying to display a pills table which lists article categories and if selected, will show only the articles from that category in an accordion style list. Each article can have multiple categories.

My models are as follows:

class Article < ActiveRecord::Base
  belongs_to :user
  has_many :article_categories
  has_many :categories, through: :article_categories
  validates :title, presence: true, length: {minimum: 3, maximum: 50}
  validates :description, presence: true, length: {minimum: 10, maximum: 300}
  validates :user_id, presence: true
end

class Category < ActiveRecord::Base
  has_many :article_categories
  has_many :articles, through: :article_categories
  validates :name, presence: true, length: { minimum: 3, maximum: 25}
  validates_uniqueness_of :name
end

class ArticleCategory < ActiveRecord::Base
  belongs_to :article
  belongs_to :category
end

My articles controller

class ArticlesController < ApplicationController
before_action :set_article, only: [:edit, :update, :show, :destroy]
before_action :require_user, except: [:index, :show,]
before_action :require_same_user, only: [:edit, :update, :destroy]

def index
  @articles = Article.paginate(page: params[:page], per_page: 15)
  @article_list = @articles.group_by { |t| t.categories.name }
  @categories = Category.all
end 

My article index.html.erb is

<h1 align="center">Listing all articles by Category</h1>
<div class="container">
 <div align="center">

  <h2 align="center">Find your articles below</h2>
    <ul class="col-md-offset-3 nav nav-pills">
      <% @categories.each do |category| %>
        <li><a data-toggle="pill" href="#<%= category.name %>"><%= category.name %></a></li>
      <% end %>
    </ul>
 </div>
<% @article_list.each do |category, article_items| %>
 <div class="tab-content">
  <div id="<%= category %>" class "tab-pane fade in">
   <div class="panel-group" id="accordion">
    <% article_items.each do |article_item| %>
      <div class="panel panel-default">
        <div class="panel-heading" >
          <h4 class="panel-title">
            <a data-toggle="collapse" data-parent="#accordion" href="#<%= article_item.title %>">
            <%= article_item.title %></a>
          </h4>
        </div>
        <div id="<%= article_item.title %>" class="panel-collapse collapse">
          <div class="panel-body"><%=article_item.description %></div>
        </div>
      </div>
    <% end %>   
   </div>  
  </div> 
 </div>
<% end %>

</div>

This displays both the pills and the accordion style but does not link together. How can I ensure that the categories pill tab only displays the associated articles in the accordion?

Upvotes: 1

Views: 371

Answers (1)

Steve
Steve

Reputation: 21

I ended up changing the code a little to get it to work. The first thing I did was ues the Categories controller and index page instead of the articles controller and index page.

In my Categories controller I have this:

def index
  @categories = Category.all
end

And in my index.html.erb I changed it to this:

<h1 align="center">Listing all articles by Category</h1>
<div class="container">
  <div align="center">
      <h2 align="center">FAQ</h2>
        <ul class="col-md-offset-3 nav nav-pills">
          <% @categories.all.each do |cats| %>
            <li><a data-toggle="pill" href="#<%= cats.name %>"><%= cats.name %></a></li>
          <% end %>
        </ul>
  </div>
  <div class="tab-content">
    <% @categories.all.each do |cat| %>
      <div id="<%= cat.name %>" class="tab-pane fade">
        <div class="panel-group" id="accordion<%=cat.id%>">
          <% cat.articles.each do |article| %>
            <div class="panel panel-default">
              <div class="panel-heading" >
                <h4 class="panel-title">
                  <a data-toggle="collapse" data-parent="#accordion<%=cat.id%>" href="#<%= cat.name%><%= article.id %>">
                  <%= article.title %></a>
                </h4>
              </div>
              <div id="<%= cat.name%><%= article.id %>" class="panel-collapse collapse">
                <div class="panel-body"><%=article.description %></div>
              </div>
            </div>
          <% end %>
        </div> 
      </div>
    <% end %>
  </div>
</div>

This allows the pills to open up an accordion of all the articles in the category with unique ids for each accordion and article displayed so that all panels work appropriately even when some articles can be found in multiple accordions.

Thanks for the help.

Upvotes: 0

Related Questions