Day 79 - #100DaysofCode - My Completed Ruby On Rails Project
Tags: 100daysofcode
Published: 2020-08-18 18:40:04

<h1><center> My First Ruby on Rails Project </center></h1>

{% github SincerelyBrittany/b-owned %}

<h3><center> <u>The Idea/Concept </u></center></h3>
The third project for my bootcamp had a few requirements, but the main one was that it had to be built using Ruby on Rails. I thought hard about what I wanted to build and cared about. I found myself looking for black businesses to contribute to, however, I found myself struggling. I constantly found myself searching on instagram and twitter for hashtags or other things to find black-owned businesses. I thought to myself wouldn't it be cool to have a website that I could go to to find black owned companies in one designated place? Something like a similar to a yelp for black businesses.  

A place where I could search for a business and find out more about it or follow it? Or as a black owned business owner, if I could create an account and add my businesses? I decided to attempt to build this for my rails project!

<h3><center> <u> Questions To Ask Myself Before Building </u></center></h3>
First, I had to answer these questions for each user on my site:

1. Who is your User? 
2. What is their pain point? 
3. How do they use our solution to overcome this problem?

<h6><center> <u> A Searcher/Regular User </u></center></h6>
As a typical/search user, I want to see and be able to search for companies on the website so that I can follow them, add them to a list, and visit their websites/buy from them. I want to easily find companies and buy products that I like. 

<h6><center> <u> A Business Owner User </u></center></h6>
As an owner, I want to be able to add my businesses to the website, so that users can visit my companies, see what I offer and purchase from me. I want to get users to easily find my business and buy my products.

<h6><center> <u> An Admin User </u></center></h6>
As an administrator, I want to be able to CRUD all things on the application and be able to stop unnecessary or un-useful information from being added to the application.

<h3><center> <u> The Setup </u></center></h3>
Next, I created a skeleton app and figured out some of my models.

```
Admin
CRUD EVERYTHING - Rails_admin gem

User

Favorites
has_many :favorites
has_many :favorite_companies, through:favorites

Lists
has_many :lists (that they created)
has_many :company_lists
has_many :companies, through: company_lists

Lists
belongs_to :user 
has_many :company_lists
has_many :companies, through :company

Company Owner
has_many companies 

Company
belongs_to :company_owner
has_many :favorites

company_lists
	belongs_to list
	belongs_to company 	

Favorite
belongs_to :user 
belongs_to :company

liked :boolean
```

I even took it a step further and attempted to figure out what kind of things I would like to be able to see or do within my rails console after implementing my potential schema: 

```
Admin – CAN CRUD EVERYTHING – ME 

User
	Username:
	User.list.all
	User.favorites.all

	Favorites
Boolean :liked?
	Lists
has_many :lists (that they created)
has_many :company_lists
has_many :companies, through: company_lists

Lists
belongs_to :user 
has_many :company_lists
has_many :companies, through :company


Company Owner
Name
Company_id 

Company
Title
Description
Contact Info
Location
Social Media 


company_lists
	belongs_to list
	belongs_to company 	

Favorite
belongs_to :user 
belongs_to :company

liked :boolean
```

<h3><center> <u>The Struggles </u></center></h3>

<h6><center> <u> Setting Up Users </u></center></h6>
One area where I struggled was with was setting up the users. I had three different types of users! There was the regular user, the business owner user, and administrator. As I went through labs and googled like a maniac, I realized that the easiest way to go about this was to add a boolean to my users that would show if the user was an administrator, an owner, or a regular user.  

I added the following migration to my users table, 

```
rails g migration add_admin_to_user admin:boolean
rails g migration add_owner_to_user owner:boolean 
```

After that I was able to create users based off if the boolean was true or false for various users and I was able to set up users using the rails_admin gem. I covered how I added the rails admin gem to my project in the following post:

{% link https://dev.to/sincerelybrittany/day-68-100daysofcode-making-sure-only-admin-can-crud-application-w-o-cancancan-43gd  %}

<h6><center> <u> Allowing Users to Follow/ Unfollow  </u></center></h6>

After setting that all up I began to code and a lot of it stressed me out! But I think the main issue I ran into was when it was time to create the follow/unfollow function on my application. As you can see, based of the set-up above, my original plan was to build a favorite using a boolean. If someone followed a company then the boolean would be true and if someone unfollowed, the boolean would be false. After going crazy for a while, I spoke with my cohort lead who told me that it was best to get rid of the boolean in my favorites/follow bar and just see if it exist and then it should delete that row when a favorite does not exist! THAT MAKES SO MUCH SENSE! I ended up completing it and wrote about my updates solution in a previous blog post:

{% link https://dev.to/sincerelybrittany/day-66-100daysofcode-creating-a-follow-unfollow-in-rails-ocd %}


In addition, I decided to add a comment section for companies.

I added a comments table that contains a user and company foreign key:

```
  create_table "comments", force: :cascade do |t|
    t.string "content"
    t.integer "user_id"
    t.integer "company_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["company_id"], name: "index_comments_on_company_id"
    t.index ["user_id"], name: "index_comments_on_user_id"
  end
```  

Then, I updated the comment, user, and company controller:

```
class Comment < ApplicationRecord
    belongs_to :user
    belongs_to :company
    validates :content, presence: true, length: {maximum: 250}

    accepts_nested_attributes_for :user
    accepts_nested_attributes_for :company
    
```

```
class User < ApplicationRecord
    has_many :comments, dependent: :destroy
end
```

```
class Company < ApplicationRecord
    has_many :comments, dependent: :destroy
    has_many :users, through: :comments
end 
```

Based off the models, you can see that I wanted a user to be able to have many comments and a company to be able to have many users and comments. In the views, I was able to build comments on a company using the form_for tag, like so:

```
<div class="center">
<%= form_for @company.comments.build do |f| %>
  <%= f.hidden_field :company_id %>
  <p>
  </p>  
  <p>
    <%= f.label :content, "Add a New Comment" %><br>
    <%= f.text_area :content %>
  </p>
  <br/>
  <%= f.submit "Create", :class => "myButton" %>
<% end %>
</div>
```

The above code creates a comment for a company and sends the comment content and the hidden company_id in the params. From there, the information is handled in the comment controller:

```
class CommentsController < ApplicationController
  before_action :authenticate_user, only: [:create]
  
  def create
    @comment = Comment.new(comment_params)
    @comment.user = current_user
    if @comment.save
     redirect_to @comment.company
    else 
      redirect_to @comment.company, alert: "Comment not saved"
    end 
  end
```

The comments controller creates the comment and gives it a user. If it is saved it redirects to that company page and if it is not saved, an alert is given to the user. 

<h6><center> <u> Telephone Number Format  </u></center></h6>

Something that was driving me crazy while creating companies was that the telephone number was not formatted correctly. So I googled how I could fix this and found the following<a href="https://stackoverflow.com/questions/3368016/ruby-on-rails-validating-and-changing-a-phone-number"> Stack Overflow Question</a>. With this, I was able to add the following method to my companies controller:

```
class Company < ApplicationRecord
    def phone=(num)
      num.gsub!(/\D/, '') if num.is_a?(String)
      self[:phone] = num.to_i
    end
end
```

Then I implemented the method inside of my companies show page like this:

```
<%# Displays company phone number %>
<p>Phone: <%= number_to_phone(@company.phone) %></p>
```

Now a companies phone number is formatted correctly. 

<h3><center> <u> What is next? </u></center></h3>
In the future, I plan to allow a user to search by category and I have other ideas on how to expand my application. I am excited to share my project with the world. It was not easy, but I am glad I completed it and I think I am beginning to love Ruby on Rails. 

As always, thanks for reading!

Sincerely, 
Brittany

Song of the day:

{% youtube XDCXT7C7lnk %}