ga-wdi-boston / capstone-project

Other
3 stars 28 forks source link

ERD - User Owned #615

Closed rrdaniels85 closed 7 years ago

rrdaniels85 commented 7 years ago

Good morning!

I had a question regarding how I am setting up my API and want to make sure that how I'm handling it meets the requirement of having anything updated or deleted be 'user owned'. I have attached an image of my ERD for the project. I am doing an aquarium management application for people who are fish enthusiasts and have multiple aquariums. As you can see, a user has many tanks and then a tank has many animals. I am confident that the tanks are user owned but want to make sure that I'm understanding the animals piece correctly.

Here are my models: USER

class User < ApplicationRecord
  include Authentication
  has_many :examples
  has_many :tanks
end

TANK

class Tank < ApplicationRecord
  belongs_to :user, foreign_key: 'user_id'

  validates :name, presence: true
  validates :water, presence: true
  enum water: { salt: 'Salt', fresh: 'Fresh' }

end

Planned MODEL FOR ANIMALS:

class Animal < ApplicationRecord
  belongs_to :tank, foreign_key: 'tank_id'

  validates :name, presence: true
  validates :species, presence: true
  validates :color, presence: true
end

For my controller for animals, I was planning on doing this:

class AnimalsController < ProtectedController

  def create
    @animal = current_user.tanks.find(params[:tank_id]).animals.build(animal_params)

    if @animal.save
      render json: @animal
    else
      render json: @animal.errors.to_a, status: :unprocessable_entity
    end
  end

  def update
    @animal = Animal.joins(:tank).where(tanks: {user_id: current_user.id}).find(params[:id])

    if @animal.update_attributes(animal_params)
      render json: @animal
    else
      render json: @animal.errors.to_a, status: :unprocessable_entity
    end
  end

  def destroy
    @animal = Animal.joins(:tank).where(tanks: {user_id: current_user.id, id: params[:tank_id]}).find_by(animals: {id: params[:id]})
    if @animal.destroy
      render json: {id: @animal.id}
    else
      render json: {id: @animal.id}, status: :unprocessable_entity
    end
  end

I did not want to do a user has many animals through tanks because this seems unnecessary given that a fish can only belong to one tank. I believe that with using this approach, only the user that owns the tank can add, update, or delete the fish. Would this meet the 'user owned' requirement for the fish/animals? Or am I thinking about this the wrong way? capstone-erd

BenGitsCode commented 7 years ago

If only the user that owns the tank can add update or delete the respective animal/fish, then it would meet the requirements for resource ownership.

I notice you say that you're planning on that controller code, try it and feel free to leave this open while you build and test that.

rrdaniels85 commented 7 years ago

Thanks! I'll give it a go!

rrdaniels85 commented 7 years ago

So, this approach appears to be working. When a user tries to create, update, or delete an animal in a tank that is not user owned, they get the following error:

HTTP/1.1 404 Not Found
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: application/json; charset=utf-8
Cache-Control: no-cache
X-Request-Id: 7884ca13-1a48-422b-9bcf-1b4021c89856
X-Runtime: 0.006415
Vary: Origin
Transfer-Encoding: chunked

{"error":{"message":"Not Found"}}

So it prevents them from being able to do anything. Is this ok?