Я пытаюсь проверить вводимые пользователем данные на стороне сервера в приложении Rails с React as view. Обычно я делаю вызовы ax ios Rails API следующим образом:
const Script = props => {
const [script, setScript] = useState({})
const [scene, setScene] = useState({})
const [loaded, setLoaded] = useState(false)
useEffect(() => {
const scriptID = props.match.params.id
const url = `/api/v1/scripts/${scriptID}`
axios.get(url)
.then( resp => {
setScript(resp.data)
setLoaded(true)
})
.catch(resp => console.log(resp))
}, [])
const handleChange = (e) => {
e.preventDefault()
setScene(Object.assign({}, scene, {[e.target.name]: e.target.value}))
}
const handleSubmit = (e) => {
e.preventDefault()
const csrfToken = document.querySelector('[name=csrf-token]').content
axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken
const script_id = script.data.id
axios.post('/api/v1/scenes', {scene, script_id})
.then(resp => {
const included = [...script.included, resp.data.data]
setScript({...script, included})
})
.catch(err => {
console.log(err.response.data.error)
})
.finally(() => {
setScene({name: '', description: ''})
})
}
Все данные передаются в компонент реакции с формой.
return (
<div className="wrapper">
{
loaded &&
<Fragment>
.
.
.
<SceneForm
handleChange={handleChange}
handleSubmit={handleSubmit}
attributes={script.data.attributes}
scene={scene}
/>
</Fragment>
}
</div>
)
В этой форме у меня есть поле имени и соответствующее имя в Rails имеют уникальность проверки: true. все работает нормально, если я ввожу действительное (уникальное) имя.
Я попытался выполнить проверку, но результат меня не удовлетворил. (Это работает в целом: мой метод no_errors?
выполняет то, что должен делать, и я получаю статус 403) Это часть контроллера:
def create
scene = script.scenes.new(scene_params)
if no_error?(scene)
if scene.save
render json: SceneSerializer.new(scene).serialized_json
else
render json: { error: scene.errors.messages }, status: 422
# render json: { error: scene.errors.messages[:name] }, status: 423
end
else
render json: { error: "name must be unique" }, status: 403
end
end
.
.
.
private
def no_error?(scene)
Scene.where(name: scene.name, script_id: scene.script_id).empty?
end
Если я ввожу существующее имя, я получаю консоль .log следующим образом:
скриншот
Вот что меня беспокоит: я не доволен своим подходом к обработке ошибок в целом. Я не хочу, чтобы сообщение 403 регистрировалось в консоли (в первую очередь я хочу избежать этого сообщения). Моя идея состоит в том, чтобы использовать подход «простой формы»: сделать границу моего поля красной и опубликовать сообщение об ошибке под полем, без вывода на консоль ... И еще одно примечание: правильный ли статус 403? Я думал о 422, но не был уверен ...
Заранее спасибо за идеи!