Day 74 : #100DaysofCode - Finished Adding Categories
Tags: 100daysofcode
Published: 2020-08-14 03:16:36

I was pretty stressed out setting up my categories today. The first part was easy, create a model and create a migration that will add the id to the post model.

<h3><center> Create Model </center></h3>

```
rails g model category name:string desc:text 
```

<h3><center> Add Columns To Posts Migration </center></h3>

```
rails generate migration AddColumnsToPosts category_id:integer
```

I realized I want to show all categories and show post based off a category selected so I needed a Category controller:

<h3><center> Category Controller </center></h3>

```
rails g controller Category
```

Now I had to set up my models to reflect the following: 

<h3><center> Post Model </center></h3>

```
class Post < ApplicationRecord
   belongs_to :category
end
```

<h3><center> Category Model </center></h3>

```
class Category < ApplicationRecord
    has_many :posts
end
```

The next part took some google searching, how can I display all of the categories in a drop down? When I select a category  in the dropdown, how will I display the post associated with that category?

The <a href="https://apidock.com/rails/ActionView/Helpers/FormTagHelper/select_tag"> Select Tag and options_from_collection_for_select </a> is how!

I added the following to my categories index view page:

```
<%= form_tag posts_path, method: :get do %>
    <%= select_tag "category_id", options_from_collection_for_select(Category.all, "id", "name"), {:include_blank => 'All Categories'} %>
    <%= submit_tag "Search", name: nil, :class => "myButton" %>
<% end %>
```

The breakdown/what I think I understand.

``select_tag(name, option_tags = nil, options = {})``

``form_tag posts_path, method: :get do`` makes a get request to the posts_path

``select_tag "category_id"`` is the name that will be passed on in the params.

``options_from_collection_for_select(Category.all, "id", "name")`` creates a dropdown selection box for all categories, passes its id for the params, and displays the name in the dropdown list. 

``{:include_blank => 'All Categories'}`` displays "Search By Category" in the dropdown before anything is selected, it is like a placeholder.

<h3><center> The Post Controller </center></h3>

This caused me a bit of a headache, I struggled with trying to figure out WHY my dropdown failed to show me ALL my post again when I pressed "All Categories" from the ``{:include_blank => 'All Categories'}``. I figured out with a byebug that when I search for that, my category_id was empty! So I added ``if params[:category_id] && !params[:category_id].empty?`` to my controller to fix that issue.


```
class PostsController < ApplicationController
  before_action :authenticate_user, except: [:index]
    def index
     if params[:category_id] && !params[:category_id].empty?
            @category = params[:category_id]
            @posts = Post.where(category_id: @category)
            render 'index'
      else
        @posts = Post.all
        @categories = Category.all
      end
    end
```

The above checks to see if the params hold a ``category_id`` and makes sure that the ``category_id`` is NOT empty. If those two things are true then it will search through all posts where the ``category_id`` is the one that matches the params.

If the ``category_id`` is empty or if no one has searched by category, the index page will display all of the posts and give the dropdown form access to all of the categories still. 

This was a process but I definitely learned a lot today.

As always, thanks for reading!

Sincerely, 
Brittany

Song of the day:

{% youtube jo3aBksMKgs %}