1

I'm currently using a controller to receive POST with one json object at a time. And I want it change to receiving the whole array. How can I modify my controller?

Current Controller

def create
  respond_to do |format|

  @targetrecord = TargetRecord.new(targetrecord_params)
  @targetrecord.save

    if @targetrecord.save
      format.json{ render :json => @targetrecord.to_json ,status: 200 }
    else
      format.json { render json: @targetrecord.errors, status: 404 }
    end

  end
 end
end

def targetrecord_params

  params.require(:targetrecord).permit(:id, :uuid, :manor, :mac, :beacon_type, :longitude, :latitude, :address, :findTime, :rssi, :finderID, :created_at, :updated_at )

end

I'm sending the POST as below right now

"targetrecord":

{"id":"","name":"",.....}

And I want to send multiple sets as an array like

"targetrecord":[

{"id":"1","name":"",.....},
{"id":"2","name":"",.....},
....]

How can I let my controller know that she needs to extract and create one by one? Thanks a lot!

2
  • How do you want it to behave if one fails to create? Commented Jun 11, 2016 at 15:56
  • just simply show an error or do nothing are both ok! Server will do the posting job! Commented Jun 11, 2016 at 15:57

1 Answer 1

1

If you are POSTing an array, then the array will just be part of your params object when processed by the controller action. So you should be able to loop through the array and create an array of TargetRecord objects. You'll need to modify your targetrecord_params method to allow it to accept an argument since you can't just look at 'params' in that context once you make the change. You'll also need to find a way to track whether or not all the records have saved successfully.

I haven't tested this code, but something like this should get you going in the right direction, I think:

    def create
        respond_to do |format|

        @targetrecords = []
        save_succeeded = true
        params[:targetrecord].each do |record|
            tr = TargetRecord.new(targetrecord_params(record))
            save_succeeded = false unless tr.save
            targetrecords << tr
        end

            if save_succeeded
                format.json{ render :json => @targetrecord.to_json ,status: 200 }
            else
                format.json { render json: @targetrecord.errors, status: 404 }
            end

        end
     end
    end

    def targetrecord_params(record)
        record.require(:targetrecord).permit(:id, :uuid, :manor, :mac, :beacon_type, :longitude, :latitude, :address, :findTime, :rssi, :finderID, :created_at, :updated_at )
    end
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks! But I have a few questions. What does @targetrecords = [] mean here? Why do we need to announce it? And what does " << ", in the " targetrecords << tr " do? Thanks again!
What you were doing before handled only one TargetRecord but you need to handle a collection of them, correct? So, in this case, I'm creating an instance variable that contains an array of TargetRecord objects. That way you can deal with your collection of objects instead of just one. So @targetrecords = [] declares the instance variable as an array and << adds each TargetRecord object to the array as you loop through the array in the parameters and convert each parameter item to a Ruby object.
I've tried it and something went wrong. It said " param is missing or the value is empty: targetrecord " and it stop at the record.require(:targetrecord).permit(:id,....
Right - as I mentioned above, this isn't tested code. I don't know what params you are POST-ing so I don't know how to build an exact example. You need to tailor this to match whatever params your controller action is receiving. To debug this, examine your params at the point(s) where the code is failing. You can do that by using a debugger like pry or byebug, or by using puts and looking at your params at the point where the code is failing.
For example, when your code hits the targetrecord_params method, you need to examine what the 'record' value is and modify the permitted attributes accordingly. It may be that you just have an array value with id, uuid, manor, etc. In that case, you would omit the require(:targetrecord) statement because you're not expecting a param called 'targetrecord'! Remember that the purpose of your targetrecord_params is just to whitelist expected model attributes.
|

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.