Reputation: 5251
I am using Rails and React. I have two models: schedule
and worker
. worker belongs_to schedule
and schedule has_many workers
. I want to make an update request to rails from react.
This is what the fetch
function looks like that I use to send the request:
function updateSchedule(scheduleId, date, message, workersArray, cb){
return fetch(`api/schedules/${scheduleId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
date: date,
message: message,
user_id: 1,
worker_info: workersArray
})
}).then((response) => response.json())
.then(cb);
}
sample of workersArray:
[{"id"=>54, "name"=>"Owen
Johnston", "phone"=>"111-222-3333", "created_at"=>"2017-06-13T22:17:45.769Z", "updated_at"=>"2017-06-13T22:17:45.769Z", "schedule_id"=>33}, {"id"=
>55, "name"=>"Mary Watson", "phone"=>"123-456-7890", "created_at"=>"2017-06-13T22:17:45.778Z", "updated_at"=>"2017-06-13T22:17:45.778Z", "schedule_
id"=>33}]
Schedule has date, message, and user_id attributes. Schedule also has a specific group of workers. Each worker has a name
and phone
. In short, on a specific schedule, I want to update the schedule's properties, including all the workers name and phone in it. I am having problem iterating through all the workers belonging in that schedule and updating parameters of each worker.
This is the general idea. I am having problem making update
method to work.
def update
@schedule = Schedule.find(params[:id])
if @schedule.update_attributes(schedule_params)
worker_params["worker_info"].each do |w|
@worker = Worker.find(w.id)
@worker.update_attributes!
end
render json: @schedule
else
render json: @schedule, status: :unprocessable_entity
end
end
...
def schedule_params
params.require(:schedule).permit(:date, :message, :user_id)
end
def worker_params
params.permit(worker_info: [:name, :phone])
end
How can I send a put request from react to rails and tell Rails to update the schedule and all the workers associated to the schedule?
Upvotes: 1
Views: 1112
Reputation: 23859
Although I see a discrepancy in what you're sending to rails, let's assume that you're sending correct parameters and are able to update schedule (but not workers). The discrepancy is that you're not sending schedule
key in your params, but requiring it in this line:
params.require(:schedule).permit(:date, :message, :user_id)
Make sure that your final JSON (which you're sending to rails) is something like this:
{
"schedule": {
"date": "...your date",
"message": "...message",
"user_id": "...user_id"
}
}
Coming to the actual problem, which I believe, is not being able to update workers. Rails has a special directive for models which will ease your pain.
In your Schedule
model, write:
accepts_nested_attributes_for :workers, allow_destroy: true
This will enable the model to update its child attributes as well. Your controller needs to change a bit after this.
def schedule_params
params.require(:schedule).permit(:date, :message, :user_id, workers_attributes: [:id, :name, :phone, :_destroy])
end
Then use @schedule.update_attributes(schedule_params)
to update the schedule, as well as the workers.
Your final JSON should look like:
{
"schedule": {
"date": "...your date",
"message": "...message",
"user_id": "...user_id",
"workers_attributes": [{
"id": 123,
"name: "...name",
"phone": "...phone"
}]
}
}
You can pass an array of workers' attributes, which will define if you want to add/update/delete workers related to a schedule. You may want to read more about accepts_nested_attributes_for before proceeding.
Upvotes: 2