我正在用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
。在许可证之后,控制器中的轨道是:
team: {name:'testes team', players_attributes: [{ name: 'testes'}]}
在我看来(可能是我的错误)rails应该以这种方式提供这种关系。我测试了它删除了嵌套属性id
和team_id
但是没有效果。
Rails返回:
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
gambiarra :
@team.players.each do |player|
player.team_id = 1
end
如果我对嵌套属性执行此操作,那么在保存团队工作之前,团队1必须存在才能工作。如果我只保存团队,并且在创建关系之后,只有当我设置&#34; gambiarra&#34; 解决方案时,它才能运行。
如何解决这种关系?如上所述,我的控制器仅过滤嵌套数据的属性。如果我使用HTML提交,工作正常,如果我使用JSON作为嵌套对象,除非我强制关系在保存之前为我的播放器找到 a team_id
,否则它无法正常工作等等,rails将保存并提交正确的播放器,因为我的播放器中没有team_id
。
答案 0 :(得分:2)
您发送的参数结构不正确,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
才是必需的。