I'm figuring a problem with a nested_attribute.
team.rb:
class Team < ApplicationRecord
has_many :players, dependent: :destroy
accepts_nested_attributes_for :players, allow_destroy: true
end
console output:
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
So, i'm ignoring team_id
in controller for create and sending it as null same to player_id
. What rails is getting in controller after permit is:
team: {name:'testes team', players_attributes: [{ name: 'testes'}]}
In my opinion (prob my mistake) rails should feed this relation in exactly this way. I tested it removing the nested attribute id
and team_id
but doesn't works.
Rails return:
bodyText: "{"players.team":["must exist"]}
controller:
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
If i do this to the nested attribute BEFORE save team it works, team 1 must exists for it to work. If i save only the team and after create the relation it DOESN'T works either, only if I set the "gambiarra" solution.
How to solve this relation? As mentioned, my controller is filtering for only attributes for nested data. If i submit with HTML, works fine, if i use a JSON as nested objects, it doesn't work unless i force the relation to find a team_id
for my player before save and so on, rails will save and commit the right player as is expected to do without a team_id
in my player.
The structure of the params you are sending is incorrect, rails expects something like this in order to work with nested attributes :
{
"computer": {
"speakers_attributes": {
"0": {
"power": "1"
}
}
}
}
Notice three things:
computer: null
was removed; you don't need to specify computer
attribute since its value will be set with the id
of the new computer to be created.
"0":
was added; because of the has_many :speakers
associations, you can create more than one Speaker
(you will use 1: { ... }, 2: { ... }
, and so on).
speaker:
was changed to speakers_attributes
; that's the way rails recognizes nested attributes values.
Now that the parameters had been set correctly, you need to do two more things:
Confirm that your associations are set correctly
class Computer < ApplicationRecord has_many :speakers, dependent: :destroy accepts_nested_attributes_for :speakers, allow_destroy: true end class Speaker < ApplicationRecord belongs_to :computer end
Properly setup your controller
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
Here @computer.speakers.build
is neessary only if you will be creating nested forms using form helpers.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.