React通过POST请求如何让Rails后端对象保存到正确外键对应的关联记录下
问题根因&修复步骤
1. 后端ToddlersController的set_daycare方法语法错误
你当前的写法没有为find_by指定查询字段,非法参数会导致方法无法正确匹配对应ID的Daycare记录,最终默认返回第一条ID=1的记录:
# 错误写法 def set_daycare @daycare = Daycare.find_by(params[:daycare_id]) end
修改为以下任意一种即可:
# 写法1:用find直接按ID查询,不存在时自动返回404 def set_daycare @daycare = Daycare.find(params[:daycare_id]) end # 写法2:明确指定find_by的查询字段 def set_daycare @daycare = Daycare.find_by(id: params[:daycare_id]) # 可加兜底逻辑避免空指针 render json: {error: "Daycare not found"}, status: 404 unless @daycare end
同时确认config/routes.rb配置了正确的嵌套路由:
resources :daycares do resources :toddlers end
2. 前端表单下拉选择逻辑完全失效
现有代码的下拉框存在3个问题:
- 两个选项的
value都绑定了同一个this.props.daycare.id,无论选哪个值都相同 - 下拉框没有绑定
onChange事件,选中值不会同步到组件state - state未声明
daycare_id字段,提交时没有携带选中的机构ID
修复步骤:
- 打开注释的
mapStateToProps,将全局存储的全量Daycare列表传入组件props - 初始化state时添加
daycare_id字段 - 重写下拉框代码,遍历Daycare列表生成选项,绑定
onChange事件 - 提交表单时使用state中存储的选中
daycare_id,而非固定的props值 - 修正表单提交后的清空逻辑
修复后的表单核心代码:
import React, { Component } from 'react' import { connect } from 'react-redux' import { submitToddlers } from '../../actions/toddlerActions' class DaycareForm extends Component { constructor() { super() this.state = { name: '', birthday: '', contact: '', phone: '', allergy: '', daycare_id: '' // 新增外键字段 } } handleOnChange = (event) => { console.log(event.target.value, "Daycare Form: handle on change") this.setState({[event.target.name]: event.target.value}) } handleOnSubmit = (event) => { event.preventDefault() // 提交时使用state里选中的daycare_id this.props.submitToddlers(this.state, this.state.daycare_id) // 正确清空所有表单字段 this.setState({ name: '', birthday: '', contact: '', phone: '', allergy: '', daycare_id: '' }) } render() { return ( <div> <form onSubmit={this.handleOnSubmit}> <br /> <h4>New Student</h4> <label><u>Name</u>: </label> <input type="text" name="name" onChange={this.handleOnChange} value={this.state.name} placeholder="First name, last name..." required /><br /> <label><u>Birthday</u>: </label> <input type="text" name="birthday" onChange={this.handleOnChange} value={this.state.birthday} placeholder="YYYY-MM-DD..." required /><br /> <label><u>Emergency Contact</u>: </label> <input type="text" name="contact" onChange={this.handleOnChange} value={this.state.contact} placeholder="First name, last name..." required /><br /> <label><u>Phone</u>: </label> <input type="text" name="phone" onChange={this.handleOnChange} value={this.state.phone} placeholder="##########" required /><br /> <label><u>Allergy</u>: </label> <input type="text" name="allergy" onChange={this.handleOnChange} value={this.state.allergy} placeholder="Allergy..." required /><br /><br /> {/* 重写下拉框,遍历生成选项 */} <select name="daycare_id" id="daycare" required onChange={this.handleOnChange} value={this.state.daycare_id}> <option value="">Select Daycare</option> {this.props.daycares.map(daycare => ( <option key={daycare.id} value={daycare.id}>{daycare.name}</option> ))} </select> <input type="submit" value="Submit"/> </form> </div> ) } } const mapStateToProps = (state) => { return { daycares: state.daycares, // 确保你的store里存储了全量Daycare列表 getToddlers: state.toddlers, loading: state.loading } } export default connect(mapStateToProps, { submitToddlers })(DaycareForm)
内容的提问来源于stack exchange,提问作者Ifeoluwa Akinremi-Wade
相关产品推荐
相关产品推荐

