问题描述
所以我正在尝试使用 Rails API、主动存储和反应前端将音频 mp3 添加到我的后端。似乎协会被搞砸了或没有被阅读?我试过切换所有代码 请帮忙
我设置了我的模型
class Audible < ApplicationRecord
has_many :reviews
has_one_attached :track
end
我设置了我的强参数
def audible_params
params.require(:audible).permit(:title,:by,:language,:audio_file,:track,:belongs_to)
end
但是给了我这个错误,下面是我回来的参数
ActionController::ParameterMissing (param is missing or the value is empty: audible):
app/controllers/audibles_controller.rb:49:in `audible_p
in the console I get a xhr.js:175 POST http://localhost:3001/audibles 400 (Bad Request)
dispatchXhrRequest @ xhr.js:175
xhrAdapter @ xhr.js:20
dispatchRequest @ dispatchRequest.js:40
Promise.then (async)
request @ Axios.js:64
Axios.<computed> @ Axios.js:89
wrap @ bind.js:11
AddAudible._this.handleOnSubmit @ AddAudible.js:52
callCallback @ react-dom.development.js:3920
invokeGuardedCallbackDev @ react-dom.development.js:3969
invokeGuardedCallback @ react-dom.development.js:4029
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4044
executedispatch @ react-dom.development.js:8279
processdispatchQueueItemsInorder @ react-dom.development.js:8311
processdispatchQueue @ react-dom.development.js:8324
dispatchEventsForPlugins @ react-dom.development.js:8335
(anonymous) @ react-dom.development.js:8546
batchedEventUpdates$1 @ react-dom.development.js:22238
batchedEventUpdates @ react-dom.development.js:3718
dispatchEventForPluginEventSystem @ react-dom.development.js:8545
attemptTodispatchEvent @ react-dom.development.js:6028
dispatchEvent @ react-dom.development.js:5946
unstable_runWithPriority @ scheduler.development.js:654
runWithPriority$1 @ react-dom.development.js:11326
discreteUpdates$1 @ react-dom.development.js:22255
discreteUpdates @ react-dom.development.js:3730
dispatchdiscreteEvent @ react-dom.development.js:5912
AddAudible.js:56 Error: Request Failed with status code 400
at createError (createError.js:17)
at settle (settle.js:19)
at XMLHttpRequest.handleLoad (xhr.js:65)
Parameters: {"title"=>"test number 2 for track audio","by"=>"jonathan","language"=>"english","audio_file"=>"some file","track"=>#<Actiondispatch::Http::UploadedFile:0x00007f8032ad32e8 @tempfile=#<Tempfile:/var/folders/pp/lqs349x52gq18t6lndp551mc0000gn/T/RackMultipart20210304-52429-km6crs.mp3>,@original_filename="a52260a3-3686-4fef-b5e2-264482172dcc.mp3",@content_type="audio/mpeg",@headers="Content-disposition: form-data; name=\"track\"; filename=\"a52260a3-3686-4fef-b5e2-264482172dcc.mp3\"\r\nContent-Type: audio/mpeg\r\n">}
Completed 400 Bad Request in 0ms (ActiveRecord: 0.0ms | Allocations: 115)
import axios from "axios";
import React,{ Component } from "react";
import {
Form,FormGroup,Formlabel,FormControl,Button,Container,Row,Col,} from "react-bootstrap";
import { Link } from "react-router-dom";
import AudioP from "./AudioP";
//import DropZone from "./DropZone";
export class AddAudible extends Component {
state = {
title: "",by: "",language: "",audio_file: "",track:""
};
handleOnChange = (e) => {
const { name,value } = e.target;
this.setState({
[name]: value,});
};
handleFileUpload = (e) => {
console.log("handle file",e)
this.setState({
track: e.target.files[0]
})
}
handleOnSubmit = (e) => {
e.preventDefault();
const formData = new FormData()
formData.append('title',this.state.title);
formData.append('by',this.state.by);
formData.append('language',this.state.language);
formData.append('audio_file',this.state.audio_file);
formData.append('track',this.state.track);
axios
.post("http://localhost:3001/audibles",formData)
.then((res) => console.log(res,formData))
.then((data) => this.props.history.push("/"))
.catch((err) => console.log(err));
};
render() {
return (
<>
<div
style={{
margin: "40px",padding: "3%",marginLeft: "20%",width: "60%",height: "100%",backgroundColor: "white",border: "1px solid gray",fontFamily: "monospace",BoxShadow:"10px 20px",borderRadius:"20px"
}}
>
<h1 className="animate__animated animate__bounceInLeft">Add Audible</h1>
<p>
{" "}
Here we clearly,add new audibles. its simple you can either import
one that you have recorded else where. BUT,you can also record
straight from here.
</p>
</div>
<Container style={{ margin: "3%",marginLeft: "380px" }}>
<Row>
<Col xs={12}>
<Form onSubmit={this.handleOnSubmit}>
<FormGroup>
<Formlabel> Title </Formlabel>
<FormControl
type="text"
placeholder="Enter Title"
value={this.state.title}
onChange={this.handleOnChange}
name="title"
></FormControl>
<Formlabel> By: </Formlabel>
<FormControl
type="text"
placeholder="Created By"
value={this.state.by}
onChange={this.handleOnChange}
name="by"
></FormControl>
<Formlabel> Language: </Formlabel>
<FormControl
type="text"
placeholder="Language read in"
value={this.state.language}
onChange={this.handleOnChange}
name="language"
></FormControl>
<Formlabel> Audible: </Formlabel>
<FormControl
type="text"
placeholder="Delete me after track works"
value={this.state.audio_file}
onChange={this.handleOnChange}
name="audio_file"
></FormControl>
<Formlabel> Tracks: </Formlabel>
<Form.File id="formcheck-api-regular">
<Form.File.Input type="file"
accept=".mp3,audio/*"
placeholder="Audio file here"
multiple={false}
onChange={this.handleFileUpload}
name="track"/>
</Form.File>
</FormGroup>
<Button type="submit"> Submit </Button>
<Link to="/" className="btn btn-danger ml-2">
Cancel
</Link>
</Form>
</Col>
</Row>
</Container>
<div style={{
margin: "40px",marginBottom:"9%",BoxShadow:"5px 10px",borderRadius:"20px"
}}>
<h1 className="animate__animated animate__bounceInRight">Record audio</h1>
<p>
{" "}
Here we can record our book,then simply add to the new audible. This feature is coming soon!
</p>
<AudioP/>
{/* <DropZone/> */}
</div>
</>
);
}
}
export default AddAudible;
解决方法
问题在于您提交的表单数据/参数。 您的参数如下所示:
params = {"title"=>"test number 2 for track audio","by"=>"jonathan","language"=>"english","audio_file"=>"some file","track"=> ... }
但 Rails 期望嵌套哈希如下所示:
params = {"audible" => {"title"=>"test number 2 for track audio","track"=> ... }
所以在你的 React 部分你可以做这样的事情
...
let data = {
title: this.state.title,by: this.state.by,language: this.state.language,audio_file: this.state.audio_file,track: this.state.track
}
formData.append('audible',JSON.stringify(data))
...