我使用Rails作为后端,React作为我的前端。在React方面,我使用fetch对名为schedule
的模型执行POST请求。我还为worker
模型添加了子属性。
以下是我的一些代码片段。我在rails中使用has_many :through
关系。
My Rails模型和控制器:
//schedule.rb
has_many :workers, through: :rosters, dependent: :destroy
has_many :rosters, inverse_of: :schedule
//worker.rb
has_many :schedules, through: :rosters
has_many :rosters, inverse_of: :worker
//roster.rb
belongs_to :schedule
belongs_to :worker
//schedules_controller.rb
def create
@schedule = Schedule.new(schedule_params)
@workers = @schedule.rosters.build.build_worker
if @schedule.save
render json: @schedule
else
render json: @schedule, status: :unprocessable_entity
end
end
...
def schedule_params
params.permit(:date, :user_id, :workers_attributes => [:id, :name, :phone])
end
在React方面:
//inside Client.js
function postSchedule(date, cb) {
return fetch(`api/schedules`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
date: date,
user_id: 1,
workers_attributes: [{name: "Iggy Test", phone: "123-456-7890"}, {name: "Iggy Test 2", phone: "987-654-3210"}]
})
}).then((response) => response.json())
.then(cb);
};
//inside main app:
postSchedule(){
Client.postSchedule(this.state.date, (schedule) => {
this.setState({schedules: this.state.schedules.concat([schedule])})
})
};
我遇到的问题是,当我提交新的时间表时,我希望看到一个有两个工作人员的新时间表:“Iggy Test”和“Iggy Test 2”。但是,当我查看Rails内部时,它正在创建 3 工作人员:"Iggy Test"
,"Iggy Test 2"
和nil
。
以下是我提交请求时发生的情况:
Started POST "/api/schedules" for 127.0.0.1 at 2017-05-24 09:55:16 -0700
Processing by SchedulesController#create as */*
Parameters: {"date"=>"2017-05-27T02:00:00.000Z", "user_id"=>1, "workers_attributes"=>[{"name"=>"Iggy Test", "phone"=>"
123-456-7890"}, {"name"=>"Iggy Test 2", "phone"=>"987-654-3210"}], "schedule"=>{"date"=>"2017-05-27T02:00:00.000Z", "use
r_id"=>1}}
Unpermitted parameter: schedule
(0.1ms) begin transaction
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
SQL (0.4ms) INSERT INTO "schedules" ("date", "created_at", "updated_at", "user_id") VALUES (?, ?, ?, ?) [["date", 20
17-05-27 02:00:00 UTC], ["created_at", 2017-05-24 16:55:16 UTC], ["updated_at", 2017-05-24 16:55:16 UTC], ["user_id", 1]
]
SQL (0.2ms) INSERT INTO "workers" ("name", "phone", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Iggy
Test"], ["phone", "123-456-7890"], ["created_at", 2017-05-24 16:55:16 UTC], ["updated_at", 2017-05-24 16:55:16 UTC]]
SQL (0.2ms) INSERT INTO "rosters" ("worker_id", "created_at", "updated_at") VALUES (?, ?, ?) [["worker_id", 64], ["c
reated_at", 2017-05-24 16:55:16 UTC], ["updated_at", 2017-05-24 16:55:16 UTC]]
SQL (0.1ms) INSERT INTO "workers" ("name", "phone", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Iggy
Test 2"], ["phone", "987-654-3210"], ["created_at", 2017-05-24 16:55:16 UTC], ["updated_at", 2017-05-24 16:55:16 UTC]]
SQL (0.1ms) INSERT INTO "rosters" ("worker_id", "created_at", "updated_at") VALUES (?, ?, ?) [["worker_id", 65], ["c
reated_at", 2017-05-24 16:55:16 UTC], ["updated_at", 2017-05-24 16:55:16 UTC]]
SQL (0.2ms) INSERT INTO "workers" ("created_at", "updated_at") VALUES (?, ?) [["created_at", 2017-05-24 16:55:16 UTC
], ["updated_at", 2017-05-24 16:55:16 UTC]]
SQL (0.2ms) INSERT INTO "rosters" ("schedule_id", "worker_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["sc
hedule_id", 57], ["worker_id", 66], ["created_at", 2017-05-24 16:55:16 UTC], ["updated_at", 2017-05-24 16:55:16 UTC]]
SQL (0.7ms) UPDATE "rosters" SET "schedule_id" = ?, "updated_at" = ? WHERE "rosters"."id" = ? [["schedule_id", 57],
["updated_at", 2017-05-24 16:55:16 UTC], ["id", 60]]
SQL (0.1ms) UPDATE "rosters" SET "schedule_id" = ?, "updated_at" = ? WHERE "rosters"."id" = ? [["schedule_id", 57],
["updated_at", 2017-05-24 16:55:16 UTC], ["id", 61]]
(2.6ms) commit transaction
Completed 200 OK in 68ms (Views: 0.8ms | ActiveRecord: 5.6ms)
日志创建了一个计划,然后是工作人员(Iggy测试),然后是一个名单(用于该计划和Iggy测试),然后是另一个工作人员(Iggy测试2),然后是另一个名单(用于Iggy测试2和该计划) - 而不是停止,它创建了另一个工人(零)和该零工人的名单。
为什么会这样?如何修复它以仅创建指定的工作者?
作为旁注 - 如果您注意到,日志显示未经许可的参数:schedule。当我在schedule_params中添加require(:schedule)
时,该消息消失了,但它只会创建一个零工作者。
答案 0 :(得分:0)
accepts_nested_attributes_for
没有创建额外的记录。你是。
def create
@schedule = Schedule.new(schedule_params)
# This adds a worker with no attributes
@workers = @schedule.rosters.build.build_worker
if @schedule.save
render json: @schedule
else
render json: @schedule, status: :unprocessable_entity
end
end
“未经许可的参数:schedule”只是警告,在.permit
中没有列入白名单的参数哈希中存在参数。它被记录,因为它可能是一个恶意的尝试捕获大规模分配漏洞。
.require
从params散列中获取一个键,如果它不存在则引发错误,并且当你有一个平坦的params散列时,它不是你想要的。
相反,你应该调查为什么反应发送的参数包括两个未包装的参数,我不明白你为什么要发送未包装的参数和"schedule"=>{"date"=>"2017-05-27T02:00:00.000Z", "user_id"=>1}
哈希。我真的不知道React,但我猜它与this.state.schedules.concat([schedule])