My Rails app has a player class that works perfectly. Players can be created, deleted, and updated from my rails control panel without any issues.
I would like a remote counterpart to be able to join in the fun by creating players using a JSON request. Following the advice of the auto generated Rails comments above my create method : # POST /players.json
I have started sending requests to localhost:3000/players.json
The JSON
{ "player": { "name": "test", "room_id": 0, "skin_id": 1, "head_id": 2, "torso_id": 3, "legs_id": 4, "x_position": 5, "y_position": 6, "direction": 7, "action": "", "gender": "f" } }
However, I am running into this error message:
ActionController::ParameterMissing in PlayersController#create param not found: player
So I guess my question is: How should I structure the JSON I am sending?
Additional info:
Update - Player Params
Here is the player params method from my controller (as requested):
def player_params params.require(:player).permit(:name, :room_id, :skin_id, :head_id, :torso_id, :legs_id, :x_position, :y_position, :direction, :action, :gender) end
Update 2 - Player controller
class PlayersController < ApplicationController before_action :set_player, only: [:show, :edit, :update, :destroy] skip_before_filter :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'application/json' } # GET /players # GET /players.json def index @players = Player.all end # GET /players/1 # GET /players/1.json def show end # GET /players/new def new @player = Player.new end # GET /players/1/edit def edit @rooms = Room.all.map { |room| [room.name, room.id] } end # POST /players # POST /players.json def create @player = Player.new(player_params) respond_to do |format| if @player.save format.html { redirect_to @player, notice: 'Player was successfully created.' } format.json { render action: 'show', status: :created, location: @player } else format.html { render action: 'new' } format.json { render json: @player.errors, status: :unprocessable_entity } end end end # PATCH/PUT /players/1 # PATCH/PUT /players/1.json def update respond_to do |format| if @player.update(player_params) format.html { redirect_to @player, notice: 'Player was successfully updated.' } format.json { head :no_content } else format.html { render action: 'edit' } format.json { render json: @player.errors, status: :unprocessable_entity } end end end # DELETE /players/1 # DELETE /players/1.json def destroy @player.destroy respond_to do |format| format.html { redirect_to players_url } format.json { head :no_content } end end def manage_furni @player = Player.find(params[:id]) @furni = Furni.all end def add_furni player = Player.find(params[:id]) player.furnis << Furni.find(params[:furni]) redirect_to manage_furni_path(player) end def remove_furni player = Player.find(params[:id]) item = InventoryItem.find(params[:item]) player.inventory_items.delete(item) redirect_to manage_furni_path(player) end private # Use callbacks to share common setup or constraints between actions. def set_player @player = Player.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def player_params params.require(:player).permit(:name, :room_id, :skin_id, :head_id, :torso_id, :legs_id, :x_position, :y_position, :direction, :action, :gender) end end
Update 3: logs
( "Processing by PlayersController#create as JSON", "Completed 400 Bad Request in 31ms", "ActionController::ParameterMissing (param not found: player):", "app/controllers/players_controller.rb:103:in `player_params'", "app/controllers/players_controller.rb:40:in `create'", "Rendered /Users/drewwyatt/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.5ms)", "Rendered /Users/drewwyatt/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (0.9ms)", "Rendered /Users/drewwyatt/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.8ms)", "Rendered /Users/drewwyatt/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (16.3ms)" ){ }
To post JSON to a REST API endpoint, you must send an HTTP POST request to the REST API server and provide JSON data in the body of the POST message. You also need to specify the data type in the body of the POST message using the Content-Type: application/json request header.
To send the JSON with payload to the REST API endpoint, you need to enclose the JSON data in the body of the HTTP request and indicate the data type of the request body with the "Content-Type: application/json" request header.
First of all, I think your data format is ok and is not the problem here. When I ran exactly into the same problem it was because I did not send the Content-Type: application/json
header along with my request.
In Postman, you can select the 'raw' data format and then 'JSON (application/json)' to include this header. In my case it looks like this:
Alternatively, you can also try it with curl
(source):
curl -X POST -H "Content-Type: application/json" -d '{"player": {"name": "test","room_id": 0,"skin_id": 1,"head_id": 2,"torso_id": 3,"legs_id": 4,"x_position": 5,"y_position": 6,"direction": 7,"action": "","gender": "f"}}' localhost:3000/players.json
If you omit the -H "Content-Type: application/json"
, then you will receive a 400 response with the "param not found" error, if you include it it should work.
If you are trying this:
via Postman - Under form-data tab, you need to have the vars as :
player[name] player[room_id] . .
via jQuery:
$.ajax({ url: 'url', type: 'post', data: { player: { name: 'Test', room_id: '0' } } })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With