-1

我正在尝试使用 axios 发送发布请求,但我不断收到此错误。

VM679:1 POST http://localhost:3000/api/v1/reviews 422(无法处理的实体)

我在开发仅支持 Rails 6 API 的应用程序时遇到了这个挑战。

Ruby 版本:ruby 2.6.6p146 Rails:6.1.1 ReactJS

来自终端的错误消息:

    Started POST "/api/v1/reviews" for ::1 at 2021-03-05 19:08:59 +0100
Processing by Api::V1::ReviewsController#create as HTML
  Parameters: {"review"=>{"title"=>"vvdv", "description"=>"vdfdf"}, "currency_id"=>2}
  Currency Load (7.1ms)  SELECT "currencies".* FROM "currencies" WHERE "currencies"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
  ↳ app/controllers/api/v1/reviews_controller.rb:29:in `currency'
Completed 422 Unprocessable Entity in 117ms (Views: 0.8ms | ActiveRecord: 7.1ms | Allocations: 2200)

这是代码

反应

import React, { useState, useEffect, Fragment } from "react";
import axios from "axios";
import Header from "./Header";
import styled from "styled-components";
import ReviewForm from "./ReviewForm";

const Wrapper = styled.div`
  margin-left: auto;
  margin-right: auto;
`;

const Column = styled.div`
  background: #fff;
  max-width: 50%;
  width: 50%;
  float: left;
  height: 100vh;
  overflow-x: scroll;
  overflow-y: scroll;
  overflow: scroll;
  &::-webkit-scrollbar {
    display: none;
  }
  &:last-child {
    background: black;
    border-top: 1px solid rgba(255, 255, 255, 0.5);
  }
`;

const Main = styled.div`
  padding-left: 60px;
`;

export const Currency = (props) => {
  const [currency, setCurrency] = useState({});
  const [review, setReview] = useState({});
  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    const slug = props.match.params.slug;
    const url = `/api/v1/currencies/${slug}`;

    axios
      .get(url)
      .then((response) => {
        setCurrency(response.data);
        setLoaded(true);
      })
      .catch((response) => console.log(response));
  }, []);

  const handleChange = (e) => {
    e.preventDefault();

    setReview(Object.assign({}, review, { [e.target.name]: e.target.value }));

    console.log("review:", review);
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    const csrfToken = document.querySelector("[name=csrf-token]").content;
    axios.defaults.headers.common["X-CSRF-TOKEN"] = csrfToken;

    const currency_id = parseInt(currency.data.id);
    axios
      .post("/api/v1/reviews", { review, currency_id })
      .then((response) => {
        debugger;
      })
      .catch((response) => {});
  };

  return (
    <Wrapper>
      {loaded && (
        <Fragment>
          <Column>
            <Main>
              <Header
                attributes={currency.data.attributes}
                reviews={currency.included}
              />
            </Main>
            <div className="review"></div>
          </Column>
          <Column>
            <ReviewForm
              handleChange={handleChange}
              handleSubmit={handleSubmit}
              attributes={currency.data.attributes}
              review={review}
            />
          </Column>
        </Fragment>
      )}
    </Wrapper>
  );
};

export default Currency

控制器

module Api
  module V1
    class ReviewsController < ApplicationController
      protect_from_forgery with: :null_session

      def create
        review = currency.reviews.new(review_params)

        if review.save
          render json: ReviewSerializer.new(review).serialized_json
        else
          render json: { error: review.errors.full_messages }, status: 422
        end
      end

      def destroy
        review = review.find_by(:id)

        if review.destroy
          head :no_content
        else
          render json: { error: review.errors.full_messages }, status: 422
        end
      end

      private

      def currency
        @currency ||= Currency.find(params[:currency_id])
      end

      def review_params
        params.require(:review).permit(:title, :description, :rating, :currency_id)
      end
    end
  end
end

4

1 回答 1

0

你能试着把它放在if review.valid?前面if review.save看看你是否会得到一个验证异常吗?

于 2021-03-06T02:27:40.050 回答