使用嵌套属性Ruby API和react表单
我在react中有一个表单,后面使用ruby API。。。我想用一种形式来制作一种鸡尾酒,它的成分和比例……这种关系是鸡尾酒通过比例有很多成分,成分通过比例有很多鸡尾酒 后端如下所示 鸡尾酒模型使用嵌套属性Ruby API和react表单,ruby,reactjs,forms,nested-forms,nested-attributes,Ruby,Reactjs,Forms,Nested Forms,Nested Attributes,我在react中有一个表单,后面使用ruby API。。。我想用一种形式来制作一种鸡尾酒,它的成分和比例……这种关系是鸡尾酒通过比例有很多成分,成分通过比例有很多鸡尾酒 后端如下所示 鸡尾酒模型 class Cocktail < ApplicationRecord has_many :proportions has_many :ingredients, through: :proportions accepts_nested_attributes_for :proportion
class Cocktail < ApplicationRecord
has_many :proportions
has_many :ingredients, through: :proportions
accepts_nested_attributes_for :proportions
end
到目前为止,我已经能够制作出一种鸡尾酒了……我不知道我现在如何整合配料并将其添加到后端
像这样反应
import React, { useState, Fragment } from "react";
const FormCocktails = () => {
const [inputFields, setInputFields] = useState([
{ name: '', description: '', instructions: "", source: ""}
]);
///here were we get the info we need to submit
const handleSubmit = e => {
e.preventDefault();
debugger
const confObj = {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
name: inputFields[0].name,
description: inputFields[0].description,
instructions: inputFields[0].instructions,
source: inputFields[0].source
})
}
fetch("http://localhost:3000//api/v1/cocktails", confObj)
.then(response => response.json())
.then(obj => console.log(obj))
.catch(error => console.log(error))
}
const handleInputChange = (index, event) => {
const values = [...inputFields];
if (event.target.name === "name") {
values[index].name = event.target.value;
} else if(event.target.name ==="description") {
values[index].description = event.target.value;
}else if(event.target.name ==="instructions") {
values[index].instructions = event.target.value;
}else{
values[index].source = event.target.value;
}
setInputFields(values);
};
const handleAddFields = () => {
const values = [...inputFields];
inputFields.push({ instructions: "" });
setInputFields(values);
};
const handleRemoveFields = index => {
const values = [...inputFields];
values.splice(index, 1);
setInputFields(values);
};
//// { name: '', description: '', instructions: "", source: ""}
return (
<>
<h1>New Cocktails</h1>
<form onSubmit={handleSubmit}>
<div className="form-row">
{inputFields.map((inputField, index) => (
<Fragment key={`${inputField}~${index}`}>
<div className="form-group col-sm-6">
<label htmlFor="name">Cocktail Name</label>
<input
type="text"
className="form-control"
id="name"
name="name"
value={inputField.name}
onChange={event => handleInputChange(index, event)}
/>
</div>
<div className="form-group col-sm-4">
<label htmlFor="description">Cocktail description</label>
<input
type="text"
className="form-control"
id="description"
name="description"
value={inputField.description}
onChange={event => handleInputChange(index, event)}
/>
</div>
<div className="form-group col-sm-4">
<label htmlFor="instructions">Cocktail instructions</label>
<input
type="text"
className="form-control"
id="instructions"
name="instructions"
value={inputField.instructions}
onChange={event => handleInputChange(index, event)}
/>
</div>
<div className="form-group col-sm-4">
<label htmlFor="source">Cocktail source</label>
<input
type="text"
className="form-control"
id="source"
name="source"
value={inputField.source}
onChange={event => handleInputChange(index, event)}
/>
</div>
<div className="form-group col-sm-2">
<button
className="btn btn-link"
type="button"
onClick={() => handleRemoveFields(index)}
>
-
</button>
<button
className="btn btn-link"
type="button"
onClick={() => handleAddFields()}
>
+
</button>
</div>
</Fragment>
))}
</div>
<div className="submit-button">
<button
className="btn btn-primary mr-2"
type="submit"
onSubmit={(e) =>handleSubmit(e)}
>
Save
</button>
</div>
<br/>
{/* <pre>
{JSON.stringify(inputFields, null, 2)}
</pre> */}
</form>
</>
)
}
export default FormCocktails;
import React,{useState,Fragment}来自“React”;
const FormCocktails=()=>{
常量[inputFields,setInputFields]=useState([
{名称:'',描述:'',说明:'',源:'}
]);
///这是我们需要提交的信息
常量handleSubmit=e=>{
e、 预防默认值();
调试器
常数confObj={
方法:“张贴”,
标题:{
“内容类型”:“应用程序/json”,
“接受”:“应用程序/json”
},
正文:JSON.stringify({
名称:输入字段[0]。名称,
说明:输入字段[0]。说明,
说明:输入字段[0]。说明,
源:输入字段[0]。源
})
}
取回(“http://localhost:3000//api/v1/cocktails“,confObj)
.then(response=>response.json())
.then(obj=>console.log(obj))
.catch(错误=>console.log(错误))
}
常量handleInputChange=(索引、事件)=>{
常量值=[…输入字段];
如果(event.target.name==“name”){
值[index].name=event.target.value;
}else if(event.target.name==“description”){
值[索引].description=event.target.value;
}else if(event.target.name==“指令”){
值[index]。说明=event.target.value;
}否则{
值[index].source=event.target.value;
}
设置输入字段(值);
};
const handleaddields=()=>{
常量值=[…输入字段];
push({指令:});
设置输入字段(值);
};
const handleRemoveFields=索引=>{
常量值=[…输入字段];
拼接值(索引1);
设置输入字段(值);
};
////{名称:'',描述:'',说明:'',源:'}
返回(
新鸡尾酒
{inputFields.map((inputField,index)=>(
鸡尾酒名
handleInputChange(索引、事件)}
/>
鸡尾酒描述
handleInputChange(索引、事件)}
/>
鸡尾酒说明
handleInputChange(索引、事件)}
/>
鸡尾酒源
handleInputChange(索引、事件)}
/>
HandlerRemoveFields(索引)}
>
-
HandLeadFields()}
>
+
))}
handleSubmit(e)}
>
拯救
{/*
{JSON.stringify(inputFields,null,2)}
*/}
)
}
导出默认格式的鸡尾酒;
class Proportion < ApplicationRecord
belongs_to :cocktail
belongs_to :ingredient
accepts_nested_attributes_for :ingredient
end
def create
cocktail = Cocktail.new(cocktail_params)
if cocktail
cocktail.save
render json: cocktail
else
redner json: {error: "cocktail not valid "}
end
end
private
def cocktail_params
params.require(:cocktail).permit(:name, :description, :instructions, :source)
end
import React, { useState, Fragment } from "react";
const FormCocktails = () => {
const [inputFields, setInputFields] = useState([
{ name: '', description: '', instructions: "", source: ""}
]);
///here were we get the info we need to submit
const handleSubmit = e => {
e.preventDefault();
debugger
const confObj = {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
name: inputFields[0].name,
description: inputFields[0].description,
instructions: inputFields[0].instructions,
source: inputFields[0].source
})
}
fetch("http://localhost:3000//api/v1/cocktails", confObj)
.then(response => response.json())
.then(obj => console.log(obj))
.catch(error => console.log(error))
}
const handleInputChange = (index, event) => {
const values = [...inputFields];
if (event.target.name === "name") {
values[index].name = event.target.value;
} else if(event.target.name ==="description") {
values[index].description = event.target.value;
}else if(event.target.name ==="instructions") {
values[index].instructions = event.target.value;
}else{
values[index].source = event.target.value;
}
setInputFields(values);
};
const handleAddFields = () => {
const values = [...inputFields];
inputFields.push({ instructions: "" });
setInputFields(values);
};
const handleRemoveFields = index => {
const values = [...inputFields];
values.splice(index, 1);
setInputFields(values);
};
//// { name: '', description: '', instructions: "", source: ""}
return (
<>
<h1>New Cocktails</h1>
<form onSubmit={handleSubmit}>
<div className="form-row">
{inputFields.map((inputField, index) => (
<Fragment key={`${inputField}~${index}`}>
<div className="form-group col-sm-6">
<label htmlFor="name">Cocktail Name</label>
<input
type="text"
className="form-control"
id="name"
name="name"
value={inputField.name}
onChange={event => handleInputChange(index, event)}
/>
</div>
<div className="form-group col-sm-4">
<label htmlFor="description">Cocktail description</label>
<input
type="text"
className="form-control"
id="description"
name="description"
value={inputField.description}
onChange={event => handleInputChange(index, event)}
/>
</div>
<div className="form-group col-sm-4">
<label htmlFor="instructions">Cocktail instructions</label>
<input
type="text"
className="form-control"
id="instructions"
name="instructions"
value={inputField.instructions}
onChange={event => handleInputChange(index, event)}
/>
</div>
<div className="form-group col-sm-4">
<label htmlFor="source">Cocktail source</label>
<input
type="text"
className="form-control"
id="source"
name="source"
value={inputField.source}
onChange={event => handleInputChange(index, event)}
/>
</div>
<div className="form-group col-sm-2">
<button
className="btn btn-link"
type="button"
onClick={() => handleRemoveFields(index)}
>
-
</button>
<button
className="btn btn-link"
type="button"
onClick={() => handleAddFields()}
>
+
</button>
</div>
</Fragment>
))}
</div>
<div className="submit-button">
<button
className="btn btn-primary mr-2"
type="submit"
onSubmit={(e) =>handleSubmit(e)}
>
Save
</button>
</div>
<br/>
{/* <pre>
{JSON.stringify(inputFields, null, 2)}
</pre> */}
</form>
</>
)
}
export default FormCocktails;