1

I have looked at previous SO solutions on accepts_nested_attributes here and here, but I am still getting the error. I am using React as front end and Rails back end. I am trying to create a request to be sent to schedules, and from there to populate to workers.

I am using Rails 5.0.2. I have a schedule, worker, roster models.

//Schedule
  has_many :workers, through: :rosters, dependent: :destroy
  has_many :rosters
  accepts_nested_attributes_for :workers #implement accept_nested_attributes here

//Roster
  belongs_to :schedule
  belongs_to :worker

//Worker
  has_many :schedules, through: :rosters
  has_many :rosters

And here is my Schedule controller:

  def create
    @schedule = Schedule.new(schedule_params)
    if @schedule.save
      render json: @schedule
    else
      render json: @schedule, status: :unprocessable_entity
    end
  end
  ...


private

  def schedule_params
    params.permit(:date, :user_id, :workers_attributes => [:worker_id, :name, :phone])
  end

Here is the error that I got:

app/controllers/schedules_controller.rb:13:in `create'
Started POST "/api/schedules" for 127.0.0.1 at 2017-05-23 10:30:38 -0700
Processing by SchedulesController#create as */*
  Parameters: {"date"=>"2017-05-25T02:00:00.000Z", "user_id"=>1, "workers_attributes"=>{"name"=>"Iggy Test", "phone"=>"1
23-456-7890"}, "schedule"=>{"date"=>"2017-05-25T02:00:00.000Z", "user_id"=>1}}
Unpermitted parameter: schedule
Completed 500 Internal Server Error in 15ms (ActiveRecord: 0.0ms)



TypeError (no implicit conversion of Symbol into Integer):

app/controllers/schedules_controller.rb:13:in `create'

Why is my request shows Unpermitted parameter schedule? If I remove workers_attributes and only have params.permit(:date, :user_id), it works. I can't figure out why the error points to schedule. How can I make successful POST nested_attributes request to rails?

I am using fetch to do POST request from react side:

...
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"}
    })

EDIT:

After following answer from @gabrielhilal, I added require(): params.require(:schedule).permit(:date, :user_id, :workers_attributes => [:id, :name, :phone]), and edited the fetch POST on React's end to have array of objects instead of plain objects: workers_attributes: [{name: "Iggy Test", phone: "123-456-7890"}]. It does not complain anymore, and it does register new schedule. However, new workers are all nil:

#Worker.last shows:
 #<Worker id: 32, name: nil, phone: nil, created_at: "2017-05-23 19:36:09", updated_at: "2017-05-23 19:36:09">

Sorry, don't mean to create nested question, but does anyone know why it is nil?

EDIT 2:

I got it to work, sort of.

If I have

def create
    @schedule = Schedule.new(schedule_params)
    @workers = @schedule.rosters.build.build_worker
...

and

//schedule_params
params.permit(:date, :user_id, :workers_attributes => [:id, :name, :pho

ne])

I was able to have "Iggy Test" to display, but it immediately creates another nil worker.

Log:

Started POST "/api/schedules" for 127.0.0.1 at 2017-05-23 20:42:38 -0700
Processing by SchedulesController#create as */*
  Parameters: {"date"=>"2017-05-26T02:00:00.000Z", "user_id"=>1, "workers_attributes"=>[{"name"=>"Iggy Test", "phone"=>"
123-456-7890"}], "schedule"=>{"date"=>"2017-05-26T02:00:00.000Z", "user_id"=>1}}
Unpermitted parameter: schedule
   (0.1ms)  begin transaction
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  SQL (1.1ms)  INSERT INTO "schedules" ("date", "created_at", "updated_at", "user_id") VALUES (?, ?, ?, ?)  [["date", 20
17-05-26 02:00:00 UTC], ["created_at", 2017-05-24 03:42:38 UTC], ["updated_at", 2017-05-24 03:42:38 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 03:42:38 UTC], ["updated_at", 2017-05-24 03:42:38 UTC]]
  SQL (0.2ms)  INSERT INTO "rosters" ("worker_id", "created_at", "updated_at") VALUES (?, ?, ?)  [["worker_id", 56], ["c
reated_at", 2017-05-24 03:42:38 UTC], ["updated_at", 2017-05-24 03:42:38 UTC]]

  SQL (0.1ms)  INSERT INTO "workers" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", 2017-05-24 03:42:38 UTC
], ["updated_at", 2017-05-24 03:42:38 UTC]]
  SQL (0.6ms)  INSERT INTO "rosters" ("schedule_id", "worker_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["sc
hedule_id", 52], ["worker_id", 57], ["created_at", 2017-05-24 03:42:38 UTC], ["updated_at", 2017-05-24 03:42:38 UTC]]
  SQL (0.4ms)  UPDATE "rosters" SET "schedule_id" = ?, "updated_at" = ? WHERE "rosters"."id" = ?  [["schedule_id", 52],
["updated_at", 2017-05-24 03:42:38 UTC], ["id", 52]]
   (5.6ms)  commit transaction
Completed 200 OK in 417ms (Views: 6.9ms | ActiveRecord: 14.7ms)

If I modified params to have require(:schedule)

params.require(:schedule).permit(:date, :user_id, :workers_attributes => [:id, :name, :phone])

It creates a nil worker only.

Log:

Started POST "/api/schedules" for 127.0.0.1 at 2017-05-23 20:45:03 -0700
Processing by SchedulesController#create as */*
  Parameters: {"date"=>"2017-05-26T02:00:00.000Z", "user_id"=>1, "workers_attributes"=>[{"name"=>"Iggy Test", "phone"=>"
123-456-7890"}], "schedule"=>{"date"=>"2017-05-26T02:00:00.000Z", "user_id"=>1}}
   (0.1ms)  begin transaction
  User Load (0.3ms)  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-26 02:00:00 UTC], ["created_at", 2017-05-24 03:45:03 UTC], ["updated_at", 2017-05-24 03:45:03 UTC], ["user_id", 1]
]
  SQL (0.2ms)  INSERT INTO "workers" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", 2017-05-24 03:45:03 UTC
], ["updated_at", 2017-05-24 03:45:03 UTC]]

  SQL (0.3ms)  INSERT INTO "rosters" ("schedule_id", "worker_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["sc
hedule_id", 53], ["worker_id", 58], ["created_at", 2017-05-24 03:45:03 UTC], ["updated_at", 2017-05-24 03:45:03 UTC]]
   (2.4ms)  commit transaction
Completed 200 OK in 81ms (Views: 1.3ms | ActiveRecord: 8.3ms)

1 Answer 1

1

Your post:

{
  "date"=>"2017-05-25T02:00:00.000Z",
  "user_id"=>1,
  "workers_attributes"=>{
    "name"=>"Iggy Test",
    "phone"=>"123-456-7890"
  },
  "schedule"=> {
    "date"=>"2017-05-25T02:00:00.000Z",
    "user_id"=>1
  }
}

You have two issues:

  • schedule is not permitted (that's why you see the message in the logs), but it will be just ignored anyway (won't raise any error).
  • the workers_attributes should be a collection of workers and not a simple hash, so that's why you are having the error.

You should get something like the following in the post request:

{
  "date"=>"2017-05-25T02:00:00.000Z",
  "user_id"=>1,
  "workers_attributes"=>{
    "0" => {
      "name"=>"Iggy Test",
      "phone"=>"123-456-7890"
    }
  }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Hi @gabrielhilal, your answer helped to fix one problem - thanks!! I added require() in my params method, now I have: params.require(:schedule).permit(:date, :user_id, :workers_attributes => [:id, :name, :phone]). It fixes the schedule error. I also changed my POST request for workers_attributes into array of objects: workers_attributes: [{name: "Iggy Test", phone: "123-456-7890"}]. One problem, is when I do Worker.last, it shows nil attributes: <Worker id: 32, name: nil, phone: nil, created_at: "2017-05-23 19:36:09", updated_at: "2017-05-23 19:36:09">. Do you know why?
looking at your params I don't think you need the params.require(:schedule) unless you are sending everything inside schedule, such as {"schedule"=>{"date"=>"2017-05-25T02:00:00.000Z", "user_id"=>1, "workers_attributes"=>{...}}}...
When I removed it, it does not make any difference to the final result/ what's saved in DB. Worker.last still shows nil for both name and phone. It seems like Rails did not realize the parameters are there. Newly created Worker only has id, updated_at and created_at.
Try to print the schedule_params
puts schedule_params.inspect gives: <ActionController::Parameters {"date"=>"2017-05-26T02:00:00.000Z", "user_id"=>1} permitted: true>
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.