JSON Rails 一对多的嵌套属性
Nested Attributes With JSON Rails One to Many
我在想 nested_attribute 的问题。
team.rb:
class Team < ApplicationRecord
has_many :players, dependent: :destroy
accepts_nested_attributes_for :players, allow_destroy: true
end
控制台输出:
Processing by TeamsController#create as JSON
Parameters: {"team"=>{"id"=>nil, "name"=>"testes",
"players_attributes"=>[{"id"=>nil, "name"=>"dadada", "_destroy"=>false, "team_id"=>nil}]}}
Unpermitted parameter: id
因此,我忽略控制器中的 team_id
以创建并将其作为 null 发送给 player_id
。获得许可后 rails 进入控制器的是:
team: {name:'testes team', players_attributes: [{ name: 'testes'}]}
在我看来(可能是我的错误)rails 应该以这种方式提供这种关系。我测试了它删除嵌套属性 id
和 team_id
但不起作用。
Rails return:
bodyText: "{"players.team":["must exist"]}
控制器:
def create
@team = Team.create(team_params)
@team.players.each do |player|
player.team_id = 1
end
respond_to do |format|
if @team.save
format.html { redirect_to @team, notice: 'Team was successfully created.' }
format.json { render :show, status: :created, location: @team }
else
format.html { render :new }
format.json { render json: @team.errors, status: :unprocessable_entity }
end
end
end
def team_params
params.require(:team).permit(:name, players_attributes: [:name, :positions, :_destroy])
end
甘比亚拉:
@team.players.each do |player|
player.team_id = 1
end
如果我在保存团队之前对嵌套属性执行此操作,则团队 1 必须存在才能工作。如果我只保存团队并在创建关系后它也不起作用,只有当我设置 "gambiarra" 解决方案时。
如何解决这个关系?如前所述,我的控制器仅过滤嵌套数据的属性。如果我使用 HTML 提交,工作正常,如果我使用 JSON 作为嵌套对象,它不起作用,除非我强制关系找到 a team_id
我的播放器在保存 等之前,rails 将保存并提交正确的播放器,正如我的播放器中没有 team_id
时预期的那样。
您发送的参数结构不正确,rails 需要这样的东西才能使用 嵌套属性:
{
"computer": {
"speakers_attributes": {
"0": {
"power": "1"
}
}
}
}
注意三件事:
computer: null
已删除;您不需要指定 computer
属性,因为它的值将由要创建的新计算机的 id
设置。
添加了 "0":
;由于 has_many :speakers
关联,您可以创建多个 Speaker
(您将使用 1: { ... }, 2: { ... }
,依此类推)。
speaker:
改为speakers_attributes
;这就是 rails 识别 嵌套属性 值的方式。
现在参数已经设置正确,你还需要做两件事:
确认您的关联设置正确
class Computer < ApplicationRecord
has_many :speakers, dependent: :destroy
accepts_nested_attributes_for :speakers, allow_destroy: true
end
class Speaker < ApplicationRecord
belongs_to :computer
end
正确设置您的控制器
class ComputersController < ApplicationController
def new
@computer = Computer.new
@computer.speakers.build
end
def create
@computer = Computer.create(computer_params)
if @computer.save
# handle success
else
# handle error
end
end
# other actions
private
def computer_params
params.require(:computer).permit(speakers_attributes: [:power])
end
end
此处 @computer.speakers.build
仅当您要使用表单助手创建嵌套表单时才需要。
我在想 nested_attribute 的问题。
team.rb:
class Team < ApplicationRecord
has_many :players, dependent: :destroy
accepts_nested_attributes_for :players, allow_destroy: true
end
控制台输出:
Processing by TeamsController#create as JSON
Parameters: {"team"=>{"id"=>nil, "name"=>"testes",
"players_attributes"=>[{"id"=>nil, "name"=>"dadada", "_destroy"=>false, "team_id"=>nil}]}}
Unpermitted parameter: id
因此,我忽略控制器中的 team_id
以创建并将其作为 null 发送给 player_id
。获得许可后 rails 进入控制器的是:
team: {name:'testes team', players_attributes: [{ name: 'testes'}]}
在我看来(可能是我的错误)rails 应该以这种方式提供这种关系。我测试了它删除嵌套属性 id
和 team_id
但不起作用。
Rails return:
bodyText: "{"players.team":["must exist"]}
控制器:
def create
@team = Team.create(team_params)
@team.players.each do |player|
player.team_id = 1
end
respond_to do |format|
if @team.save
format.html { redirect_to @team, notice: 'Team was successfully created.' }
format.json { render :show, status: :created, location: @team }
else
format.html { render :new }
format.json { render json: @team.errors, status: :unprocessable_entity }
end
end
end
def team_params
params.require(:team).permit(:name, players_attributes: [:name, :positions, :_destroy])
end
甘比亚拉:
@team.players.each do |player|
player.team_id = 1
end
如果我在保存团队之前对嵌套属性执行此操作,则团队 1 必须存在才能工作。如果我只保存团队并在创建关系后它也不起作用,只有当我设置 "gambiarra" 解决方案时。
如何解决这个关系?如前所述,我的控制器仅过滤嵌套数据的属性。如果我使用 HTML 提交,工作正常,如果我使用 JSON 作为嵌套对象,它不起作用,除非我强制关系找到 a team_id
我的播放器在保存 等之前,rails 将保存并提交正确的播放器,正如我的播放器中没有 team_id
时预期的那样。
您发送的参数结构不正确,rails 需要这样的东西才能使用 嵌套属性:
{
"computer": {
"speakers_attributes": {
"0": {
"power": "1"
}
}
}
}
注意三件事:
computer: null
已删除;您不需要指定computer
属性,因为它的值将由要创建的新计算机的id
设置。
添加了 "0":
;由于has_many :speakers
关联,您可以创建多个Speaker
(您将使用1: { ... }, 2: { ... }
,依此类推)。speaker:
改为speakers_attributes
;这就是 rails 识别 嵌套属性 值的方式。
现在参数已经设置正确,你还需要做两件事:
确认您的关联设置正确
class Computer < ApplicationRecord has_many :speakers, dependent: :destroy accepts_nested_attributes_for :speakers, allow_destroy: true end class Speaker < ApplicationRecord belongs_to :computer end
正确设置您的控制器
class ComputersController < ApplicationController def new @computer = Computer.new @computer.speakers.build end def create @computer = Computer.create(computer_params) if @computer.save # handle success else # handle error end end # other actions private def computer_params params.require(:computer).permit(speakers_attributes: [:power]) end end
此处 @computer.speakers.build
仅当您要使用表单助手创建嵌套表单时才需要。