accept_nested_attributes_for 在 Rails 上创建了一条额外的零记录
accept_nested_attributes_for creates one extra nil record on Rails
我使用 Rails 作为后端,使用 React 作为前端。在 React 方面,我正在使用 fetch 对名为 schedule
的模型执行 POST 请求。我还为 worker
模型添加了一个子属性。
这是我的一些代码片段。我在 rails 中使用 has_many :through
关系。
我的 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) - 它没有停止,而是创建了另一个 worker (nil) 和那个 nil worker 的名册。
为什么会这样?我如何修复它以仅创建指定的工人?
附带说明 - 如果您注意到,日志会显示不允许的参数:计划。当我在我的 schedule_params 中添加 require(:schedule)
时,该消息消失了,但它只会创建一个 nil worker。
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
"Unpermitted parameter: schedule" 只是一个警告,表明参数散列中有一个参数未被 .permit
列入白名单。它被记录下来,因为它可能是恶意尝试寻找质量分配漏洞。
.require
从 params 散列中获取一个键,如果它不存在并且当你有一个平面 params 散列时不是你想要的,则会引发错误。
相反,您应该研究为什么 React 发送的参数包括未包装的参数,我不明白您为什么要同时发送未包装的参数和 "schedule"=>{"date"=>"2017-05-27T02:00:00.000Z", "user_id"=>1}
哈希。我不太了解 React,但我猜它与 this.state.schedules.concat([schedule])
有关
我使用 Rails 作为后端,使用 React 作为前端。在 React 方面,我正在使用 fetch 对名为 schedule
的模型执行 POST 请求。我还为 worker
模型添加了一个子属性。
这是我的一些代码片段。我在 rails 中使用 has_many :through
关系。
我的 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) - 它没有停止,而是创建了另一个 worker (nil) 和那个 nil worker 的名册。
为什么会这样?我如何修复它以仅创建指定的工人?
附带说明 - 如果您注意到,日志会显示不允许的参数:计划。当我在我的 schedule_params 中添加 require(:schedule)
时,该消息消失了,但它只会创建一个 nil worker。
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
"Unpermitted parameter: schedule" 只是一个警告,表明参数散列中有一个参数未被 .permit
列入白名单。它被记录下来,因为它可能是恶意尝试寻找质量分配漏洞。
.require
从 params 散列中获取一个键,如果它不存在并且当你有一个平面 params 散列时不是你想要的,则会引发错误。
相反,您应该研究为什么 React 发送的参数包括未包装的参数,我不明白您为什么要同时发送未包装的参数和 "schedule"=>{"date"=>"2017-05-27T02:00:00.000Z", "user_id"=>1}
哈希。我不太了解 React,但我猜它与 this.state.schedules.concat([schedule])