0

My app has a Rails API back end and React front end.

The ERD only has three params: a User has_many :sites, a Site belongs_to :user and has_many :pages, and a Page belongs_to :site.

All the CRUD functions work except when I try to post a page that belongs to a site to my Active Records backend.

If I look at the Rails Console, I can see the sites & the user it belongs to:

#<Site:0x00007fbc9ad9fe28 id: 94, name: "Daffy", category: "test", user_id: 1, created_at: Tue, 15 Oct 2019 13:53:23 UTC +00:00, updated_at: Tue, 15 Oct 2019 13:53:23 UTC +00:00>]

however, when I try to post a page to the site, the site ID comes back nil

#<Page:0x00007fbc9b5069c8 id: 2, content: "\"\"", site_id: nil, created_at: Tue, 15 Oct 2019 10:51:42 UTC +00:00, updated_at: Tue, 15 Oct 2019 10:51:42 UTC +00:00>]

Looking at Chrome dev tools, I get error 422:

Failed to load resource: the server responded with a status of 422 (Unprocessable Entity)
:3000/users/1/sites/94/pages/:1 

& in Network under the Preview tab, I get

{site: ["must exist"]}
site: ["must exist"]

I've taken a look at the following StackOverflow posts related to this:

POST 422 (Unprocessable Entity) in Rails? Due to the routes or the controller?

and

Validation failed Class must exist

but neither worked for in my particular case.

SitesController.rb

class SitesController < ApplicationController
  before_action :set_site, only: [:show, :update, :destroy]
  before_action :authorize_request, only: [:create]

...

  def create
    @site = Site.new(site_params)
    @current_user.sites << @site
      render json: @site, status: :created
  end

...

    def site_params
      params.require(:site).permit(:name, :category, :user_id)
    end
end

I've been going at this for a while, I'm hoping someone that knows Rails a lot better than I do can point out what I'm missing.

Noble Polygon
  • 796
  • 11
  • 36
  • I may not understand completely what is going on, but dont you want a Site.create instead of a Site.new? Site.new does not create an id until it is saved. – zakariah1 Oct 15 '19 at 14:52

1 Answers1

1

The problem is in your create action. As zakariah1 pointed out, Site.new will just initialize the Site, you need to save it in the database using Site.create.

Also, you don't need this code @current_user.sites << @site in your action. Since, your site_params have user_id, rails associations does that for you.

So here's how your controllers should look:

# sites_controller.rb
def create
  @site = Site.new(site_params)
  if @site.save
    render json: @site, status: :created
  else
    # render error
  end
end

...

def site_params
  params.require(:site).permit(:name, :category, :user_id)
end

# pages_controller.rb
def create
  @page = Page.new(page_params)
  if @page.save
    render json: @page, status: :created
  else
    # render error
  end
end

...

def page_params
  params.require(:page).permit(:name, :category, :site_id)
end
  • Thanks for your answer. It was correct except I did have to pass ```@current_user.sites << @site``` to make it work but I'm getting the ```site_id``` in my response. – Noble Polygon Oct 15 '19 at 18:23
  • @RHBlanchfield I think that's not a good practice to add, can you try this line `@site.user_id = @current_user.id` instead of `@current_user.sites << @site` and see if things work? –  Oct 16 '19 at 08:36