Hello> Im creating a Javascript SPA/Rails Api that has books and users. I using namespace in my routes,along with serializers for each model. Im not sure why im getting this error when trying to do a post fetch request for a user. Im not sure if i will have the same problem with my books. Belo you can see where in my controller at the top have Api::V1....etc for each controller. I then in my routes have my namespace routes. My rails console is running as well
Routing Error uninitialized constant Api
my controller
class Api::V1::UsersController < ApplicationController
def index
users=User.all
render json: users
end
def create
if User.find_by(:name=> user_params[:name])
user=User.find_by(:name=>user_params[:name])
redirect_to "/api/v1/users/#{user.id}"
else
user = User.create(user_params)
user.save!
render json: user
end
end
def show
user = User.find_by(:id => params[:id])
render json: user
end
private
def user_params
params.require(:user).permit(:name)
end
end
class Api::V1::BooksController < ApplicationController
def index
books = Book.all
render json: books
end
def create
book = Book.create(book_params)
book.save!
render json: book
end
def destroy
book=Book.find_by(:id => params[:id]).destroy
render json: book
end
private
def book_params
params.require(:book).permit(:title,:author,:review,:rating,:user_id)
end
end
ROUTES
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :books
end
end
end
//POST fetch for creating a User
static createUser(user) {
let newUserForm = document.getElementById('new-user-form')
newUserForm.addEventListener('submit', function(e){
e.preventDefault();
fetch('http://localhost:3000/api/v1/users', {
method: 'POST',
headers: {
'Content-Type' : 'application/json',
'Accept' : 'application/json'
},
body: JSON.stringify({
user: {
name: e.target.children[1].value
}
})
})
.then(res => {
if (!res.ok) {
throw new Error(); // Will take you to the `catch` below
}
return res.json();
})
.then (user => {
let newUser = new User(user)
console.log(user)
newUser.displayUser();
})
.catch(error => {
console.error('User class Error', error)
})
})
}
While you could naively belive that
class Api::V1::UsersControllerdoes the same thing it does not as it requires the Api module to be defined at the time the class is loaded and does not properly set the module nesting which will lead to suprising constant lookups. For example when you useUserRuby will not findApi::UserorApi::V1::Useras could be expected.There are however many more issues with this code as its riddled with poor api design descisions - potential nil errors (through the use of find_by instead of find). It should really look like this:
When creating a resource you should return a 201 CREATED response if it was successful and either include the resource in the response body or provide a location header which tells the client where they can find the resource.
If its not successful you should return a status code such as 422 Unprocessable Entity which tells the client that the server was not able to process the request with the given parameters.