Javascript / Rails API Project: Moby - Book Review App
Tags: javascript, rails, beginners, webdev
Published: 2020-09-28 02:13:18

![Moby - Book Review App](https://dev-to-uploads.s3.amazonaws.com/i/on4i2t2vqcee2sjsf6ue.png)

# Project Overview 
I just wrapped up a new single-page app to fulfill project requirements for the Javascript module in the Flatiron School Bootcamp Curriculum. I created a book review application that has a Rails API backend to serve up JSON to my Vanilla Javascript frontend. 

# Backend 
After coding in object-orientation Ruby much of the bootcamp, It was pretty fun creating the API in Rails. What felt new was creating my first API-only Rails app. I utilized the active_model_serializers gem, ActiveRecord, and Rails Controllers to serve up data to my frontend. 

Here's examples from my Book resource: 

```
create_table "books", force: :cascade do |t|
    t.string "title"
    t.string "author"
    t.string "genre"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
end
```

I used a serializer to have the most flexibility with serving the data up to the front end. 

```
class BookSerializer < ActiveModel::Serializer
  attributes :id, :title, :author, :genre
  has_many :reviews
end
```

I created some common restful controller actions to handle requests from the frontend but all my data is being rendered via JSON. 

```
class Api::V1::ReviewsController < ApplicationController
    before_action :set_review, only: [:show, :destroy]

        def index
            reviews = Review.all
            render json: @reviews
        end

        def show
            render json: @review
          end

        def create
            book = Book.find(params[:book_id])
            @review = book.reviews.build(review_params)

            if @review.save
                render json: @review, status: :created
            else
                render json: @review.errors, status: :unprocessable_entity
            end
        end


        def destroy
            @review.destroy
        end


        private

        def set_review
            @review = Review.find(params[:id])
        end

        def review_params
            params.require(:review).permit(:book_id, :body)
        end
    end
```

# Frontend 
Working on the frontend of this app really helped me to discover some knowledge gaps and learn more about object-oriented Javascript. There are a few things I needed to re-orient myself on to work with Javascript classes. The **Static** keyword helps create a class scoped variable(allBooks) that I assigned to an empty array. Next, Javascript has a constructor function for classes that provides a way of grabbing and assigning properties to a new instance of a class. Last in this example you may notice the **This** keyword. The **This** key word provides a way of referring to the context in object oriented Javascript. In this case it if referring the the new book instance. 

Javascript Book class: 
```
class Book {
    static allBooks = [];

    constructor({id, title, author = "unknown", genre = "uncategorized", reviews = [] }) {
        this.id = id
        this.title = title
        this.author = author
        this.genre = genre
        this.reviews = reviews

        Book.allBooks.push(this)
    }
}
```


# Check out the project
Thanks for taking the time to read about my journey learning more about web development. If you are interested in checking out my Rails/Javascript web app, check out the link below and feel free to leave a comment about your experience learning web development.

[Click Here to view the Moby App](https://github.com/TerryThreatt/moby)

Happy Coding, 

Terry Threatt