所以我试图使用rails API,活动存储和react前端将音频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"rnContent-Type: audio/mpegrn">}
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",
padding: "3%",
marginLeft: "20%",
marginBottom:"9%" ,
width: "60%",
height: "100%",
backgroundColor: "white",
border: "1px solid gray",
fontFamily: "monospace",
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",
"by"=>"jonathan",
"language"=>"english",
"audio_file"=>"some file",
"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))
...