[英]accept_nested_attributes_for creates one extra nil record on Rails
I am using Rails as a backend and React as my front-end. 我将Rails用作后端,将React作为我的前端。 On the React side, I am using fetch to do POST request to my model named
schedule
. 在React方面,我正在使用fetch向名为
schedule
模型执行POST请求。 I am also adding a child attributes for worker
model. 我还为
worker
模型添加了子属性。
Here are some code snippets that I have. 这是我的一些代码片段。 I am using
has_many :through
relationship in rails. 我在rails中使用
has_many :through
关系。
My Rails models and controller: 我的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
On React side: 在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])})
})
};
The problem that I have is, when I submit a new schedule, I expect to see a new schedule with two workers: "Iggy Test" and "Iggy Test 2". 我的问题是,当我提交新时间表时,我希望看到有两个工作人员的新时间表:“ Iggy Test”和“ Iggy Test 2”。 However, when I looked inside Rails, it is creating 3 workers:
"Iggy Test"
, "Iggy Test 2"
, and nil
. 但是,当我查看Rails内部时,它正在创建3个工作程序:
"Iggy Test"
, "Iggy Test 2"
和nil
。
Here is what is happening when I submit the request: 这是我提交请求时发生的事情:
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)
The log created a schedule, then a worker (Iggy Test), then a roster (for that schedule and Iggy Test), then another worker (Iggy Test 2), then another roster (for Iggy Test 2 and that schedule) - instead of stopping, it created another worker (nil) and a roster for that nil worker. 日志创建了一个日程表,然后是一个工作程序(Iggy测试),然后是一个名册(用于该日程表和Iggy Test),然后是另一个工作人员(Iggy测试2),然后是另一个名册(用于Iggy Test 2和该日程表)-而不是停止后,它创建了另一个工作人员(nil)和该工作人员的名册。
Why is it behaving such? 为什么会这样呢? How can I fix it to create only the specified workers?
如何解决它以仅创建指定的工作程序?
As a side note - if you noticed, the log says unpermitted parameter: schedule. 附带说明-如果您注意到,日志将显示不允许的参数:schedule。 That message disappears when I add
require(:schedule)
inside my schedule_params, but it would instead create only one nil worker. 当我在
require(:schedule)
添加require(:schedule)
时,该消息消失,但是它只会创建一个nil worker。
accepts_nested_attributes_for
is not creating an extra record. accepts_nested_attributes_for
没有创建额外的记录。 You are. 你是。
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
"Unpermitted parameter: schedule" is just a warning that there was a param is in the params hash that was not whitelisted by .permit
. “ Unpermitted parameter:schedule”只是一个警告,表明在params哈希中存在一个未被
.permit
列入白名单的.permit
。 It is logged since it could be a malicious attempt to fish for mass assignment vulnerabilities. 记录此日志是因为它可能是恶意企图捕获大规模分配漏洞。
.require
takes a single key from the params hash and raises an error if it not present and is not what you want when you have a flat params hash. .require
从params哈希中获取一个键,如果不存在则抛出错误,这不是您拥有平坦params哈希时所需要的。
Instead you should look into why the params sent by react include both the unwrapped params and I don't get why you are sending both the unwrapped params and a "schedule"=>{"date"=>"2017-05-27T02:00:00.000Z", "user_id"=>1}
hash. 相反,您应该研究一下为什么react发送的参数既包括未包装的参数,又不知道为什么您同时发送了未包装的参数和
"schedule"=>{"date"=>"2017-05-27T02:00:00.000Z", "user_id"=>1}
哈希。 I don't really know React but I'm guessing it has something to do with this.state.schedules.concat([schedule])
我不是很了解React,但我猜它与
this.state.schedules.concat([schedule])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.