COVIDiary pt. 7 - A Little More Action

Welcome to Part 7 of the COVIDiary project! If you’re just joining us or missed a post, here’s what we’ve done so far:

This week, we’re going to continue work on the back end, in CD-API. By the end of today, we will have basic CRUD actions for our Users and their Entries.

Today’s post will be a little long. Get yourself a Pepsi and some snacks, and settle in, friends.

Go easy on the Pepsi

#public Class Method

If you’ll recall, we added the is_public boolean to our entries table. We want users to be able to decide if others can see their posts or not. When we fetch from api/entries, we should only see the entries that have been marked as public. Let’s add a class method to our Entry class in models/entry.rb:


  # returns all the entries where is_public equals true

  def self.public

    self.all.select {|entry| entry.is_public? == true}

  end

Controller Modifications

Right now, our controllers are basically empty. Let’s build them out a bit. For the moment, we want CRUD (Create, Read, Update/edit, Destroy/delete) actions for both Users and Entries. We will probably tweak these some once we start manipulating data from the front end, but we’ll have a solid start by the end of today.

Let’s start by building out our UsersController in controllers/api/users_controller.rb. As you look through the following code snippets, remember to read the comments, which are preceded by the # symbol.


class Api::UsersController < ApplicationController


  # GET api/users

  # This action lists ALL the users in our database

  def index

    users = User.all

    render json: UserSerializer.new(users)

  end


  # POST api/users

  # This action creates a new user, given the provided parameters

  def create

    user = User.create(user_params)

    if user.save

      render json: UserSerializer.new(user)

    else

      render json: { error: "Error creating user" }

    end

  end


  # GET api/users/:id

  # This action shows a specific user, determined by the :id parameter

  def show

    user = User.find(params[:id])

    render json: UserSerializer.new(user)

  end


  # PATCH api/users/:id/

  # This action allows a user to update his or her data.

  def update

    user = User.find(params[:id])

    if user.update(user_params)

      render json: UserSerializer.new(user)

    else

      render json: { error: "Error updating user" }

    end

  end


  # DELETE api/users/:id

  # This action completely removes a user from the database

  # We may want to update this later to also destroy a user's entries

  def destroy

    user = User.find(params[:id])

    user.destroy

  end


  private


  # Determine which parameters to allow from a form submission

  def user_params

    params.require(:user).permit(

        :id,

        :first_name,

        :last_name,

        :email,

        :birth_date,

        :occupation,

        :is_essential,

        :isolation_start,

        :isolation_end,

        :about

    )

  end

end

Are you still with me?

Dr. House checking in

Let’s add the CRUD actions for our EntriesController in controllers/api/entries_controller.rb.


class Api::EntriesController < ApplicationController


# before we call a controller action, call the #set_user private method

  before_action :set_user


  # GET api/users/:user_id/entries OR api/entries

  # This action lists ALL the entries in the database OR all the entries for a given user.

  def index

    # if there is a user in the params, only show their entries.

    # Otherwise, only show the public entries.

    # TODO: edit user entries so they only show private ones if it is the current user

    entries = @user ? @user.entries : Entry.public

    options = {

        include: [:user]

    }

    render json: EntrySerializer.new(entries, options)

  end


  # POST api/users/:user_id/entries

  # This action creates a new entry assigned to a given user

  def create

    entry = @user.entries.build(entry_params)

    if entry.save

      render json: EntrySerializer.new(entry)

    else

      render json: { error: "Error creating entry" }

    end

  end


  # GET api/users/:user_id/entries/:id

  # This action shows a specific entry for a given user

  def show

    entry = Entry.find(params[:id])

    options = {

        include: [:user]

    }

    render json: EntrySerializer.new(entry, options)

  end


  # PATCH api/users/:user_id/entries/:id

  # This action allows a user to update his or her entry.

  def update

    entry = Entry.find(params[:id])

    if entry.update(entry_params)

      render json: EntrySerializer.new(entry)

    else

      render json: { error: "Error updating entry" }

    end

  end


  # DELETE api/users/:user_id/entries/:id

  # This action completely removes an entry from the database

  def destroy

    entry = Entry.find(params[:id])

    entry.destroy

  end


  private


  # This method allows us to find a specific user

  def set_user

    if params[:user_id]

      @user = User.find(params[:user_id])

    end

  end


  # Determine which parameters to allow from a form submission

  def entry_params

    params.require(:entry).permit(

        :id,

        :user_id,

        :health_rating,

        :is_symptomatic,

        :health_comments,

        :mental_health_rating,

        :mental_health_comments,

        :diary_entry,

        :is_public,

	:created_at

    )

  end

end

Coming Up

Our back end is ready to deliver information to the Client app. Next week, we’ll test that connection with a few fetch() requests to make sure everything is running smoothly.