fetch 的双命名空间路由问题
double namespaced routing issues with fetch
你好> 我正在创建一个有书籍和用户的 Javascript SPA/Rails Api。我在我的路线中使用命名空间,以及每个模型的序列化程序。我不确定为什么我在尝试为用户执行 post 提取请求时收到此错误。我不确定我的书是否会遇到同样的问题。 Belo 你可以看到我的控制器顶部的每个控制器都有 Api::V1.....等。然后我在我的路线中有我的命名空间路线。我的 rails 控制台也是 运行
路由错误
未初始化常量 Api
我的控制器
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
路线
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)
})
})
}
Define (and reopen) namespaced classes and modules using explicit
nesting. Using the scope resolution operator can lead to surprising
constant lookups due to Ruby’s lexical scoping, which depends on the
module nesting at the point of definition.
module Api
module V1
class UsersController < ApplicationController
# ...
end
end
end
虽然您可以天真地相信 class Api::V1::UsersController
做了同样的事情,但实际上并没有,因为它需要在加载 class 时定义 Api 模块,但不正确设置模块嵌套,这将导致令人惊讶的不断查找。例如,当您使用 User
时,Ruby 将找不到预期的 Api::User
或 Api::V1::User
。
然而,此代码存在更多问题,因为它充斥着糟糕的 api 设计决策——潜在的零错误(通过使用 find_by 而不是查找)。它应该看起来像这样:
# no need to repeat yourself
namespace :api do
namespace :v1 do
resources :users
resources :books
end
end
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym 'API'
end
# Acronyms should be all-caps
# https://github.com/rubocop-hq/ruby-style-guide#camelcase-classes
module API
module V1
class UsersController < ApplicationController
# GET /api/v1/users
def index
users = User.all
render json: users
end
# POST /api/v1/users
def create
user = User.new(user_params)
if user.save
render json: user,
status: :created
else
render json: { errors: user.errors.full_messages },
status: :unprocessable_entity
end
end
# GET /api/v1/users/1
def show
# Use .find instead of find_by as it will return a
# 404 - Not Found if the user is not found
user = User.find(params[:id])
render json: user
end
private
def user_params
params.require(:user).permit(:name)
end
end
end
end
module API
module V1
class BooksController < ApplicationController
# GET /api/v1/books
def index
books = Book.all
render json: books
end
# POST /api/v1/books
def create
book = Book.new(book_params)
if book.save
render json: book,
status: :created
else
render json: { errors: book.errors.full_messages },
status: :created
end
end
# DELETE /api/v1/books/1
def destroy
book = Book.find(params[:id])
book.destroy
head :ok
end
private
def book_params
params.require(:book)
.permit(:title, :author, :review, :rating, :user_id)
end
end
end
end
创建资源时,如果成功,您应该 return 一个 201 CREATED 响应,并且在响应中包含资源 body 或提供一个位置 header 告诉客户端他们在哪里可以找到资源。
如果不成功,您应该 return 一个状态代码,例如 422 Unprocessable Entity,它告诉客户端服务器无法使用给定参数处理请求。
你好> 我正在创建一个有书籍和用户的 Javascript SPA/Rails Api。我在我的路线中使用命名空间,以及每个模型的序列化程序。我不确定为什么我在尝试为用户执行 post 提取请求时收到此错误。我不确定我的书是否会遇到同样的问题。 Belo 你可以看到我的控制器顶部的每个控制器都有 Api::V1.....等。然后我在我的路线中有我的命名空间路线。我的 rails 控制台也是 运行
路由错误 未初始化常量 Api
我的控制器
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
路线
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)
})
})
}
Define (and reopen) namespaced classes and modules using explicit nesting. Using the scope resolution operator can lead to surprising constant lookups due to Ruby’s lexical scoping, which depends on the module nesting at the point of definition.
module Api
module V1
class UsersController < ApplicationController
# ...
end
end
end
虽然您可以天真地相信 class Api::V1::UsersController
做了同样的事情,但实际上并没有,因为它需要在加载 class 时定义 Api 模块,但不正确设置模块嵌套,这将导致令人惊讶的不断查找。例如,当您使用 User
时,Ruby 将找不到预期的 Api::User
或 Api::V1::User
。
然而,此代码存在更多问题,因为它充斥着糟糕的 api 设计决策——潜在的零错误(通过使用 find_by 而不是查找)。它应该看起来像这样:
# no need to repeat yourself
namespace :api do
namespace :v1 do
resources :users
resources :books
end
end
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym 'API'
end
# Acronyms should be all-caps
# https://github.com/rubocop-hq/ruby-style-guide#camelcase-classes
module API
module V1
class UsersController < ApplicationController
# GET /api/v1/users
def index
users = User.all
render json: users
end
# POST /api/v1/users
def create
user = User.new(user_params)
if user.save
render json: user,
status: :created
else
render json: { errors: user.errors.full_messages },
status: :unprocessable_entity
end
end
# GET /api/v1/users/1
def show
# Use .find instead of find_by as it will return a
# 404 - Not Found if the user is not found
user = User.find(params[:id])
render json: user
end
private
def user_params
params.require(:user).permit(:name)
end
end
end
end
module API
module V1
class BooksController < ApplicationController
# GET /api/v1/books
def index
books = Book.all
render json: books
end
# POST /api/v1/books
def create
book = Book.new(book_params)
if book.save
render json: book,
status: :created
else
render json: { errors: book.errors.full_messages },
status: :created
end
end
# DELETE /api/v1/books/1
def destroy
book = Book.find(params[:id])
book.destroy
head :ok
end
private
def book_params
params.require(:book)
.permit(:title, :author, :review, :rating, :user_id)
end
end
end
end
创建资源时,如果成功,您应该 return 一个 201 CREATED 响应,并且在响应中包含资源 body 或提供一个位置 header 告诉客户端他们在哪里可以找到资源。
如果不成功,您应该 return 一个状态代码,例如 422 Unprocessable Entity,它告诉客户端服务器无法使用给定参数处理请求。