3

I'm trying to build a choose your own adventure game using Ruby on Rails and AJAX calls, where the games are user owned resources, and each game has a sentence column, expecting an array of strings.

game {
  id: 16,
  sentences: ['hello', 'world']
}

The above does not work when passed in as the data on an AJAX patch request (though I get 200 okay), neither does the hail-mary version of:

game {
id: 16,
sentences: 'hello'
}

The rails local server states that sentences are an unpermitted parameter.

      started PATCH "/games/21" for ::1 at 2018-03-18 21:11:12 -0400
    Processing by GamesController#update as */*
    Parameters: {"game"=>{"id"=>"21", "sentences"=>["This is it: the end. You were wrong."]}, "id"=>"21"}
    User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."token" = $1 LIMIT $2  [["token", "8efb6bc10343a4415f6cbcb16d5184f2"], ["LIMIT", 1]]
    Game Load (0.4ms)  SELECT  "games".* FROM "games" WHERE "games"."user_id" = $1 AND "games"."id" = $2 LIMIT $3  [["user_id", 2], ["id", 21], ["LIMIT", 1]]
    Unpermitted parameters: :id, :sentences
    (0.1ms)  BEGIN
    (0.1ms)  COMMIT
    [active_model_serializers] Rendered GameSerializer with ActiveModelSerializers::Adapter::Json (0.38ms)
    Completed 200 OK in 5ms (Views: 0.7ms | ActiveRecord: 0.9ms)

This is maddening, because the parameter is specifically permitted in the controller.

def game_params
  params.require(:game).permit(:hope, :wisdom, :user_id, :mnemonic, :sentences)
end

I can't get the sentences column to update using AJAX, though I'd added a method to the game model per this blog post's advice.

class Game < ApplicationRecord
 belongs_to :user

 def add_sentence(words)
  sentences_will_change!
  update_attributes sentences: sentences.push(words)
 end
end

I can definitely update in the Rails console.

    [3] pry(main)> game = Game.where(:id => 16).first
    Game Load (0.3ms)  SELECT  "games".* FROM "games" WHERE 
    "games"."id" = $1 ORDER BY "games"."id" ASC LIMIT $2  [["id", 16], 
    ["LIMIT", 1]]
    => #<Game:0x007ff420f750f0
    id: 16,
    hope: nil,
    wisdom: nil,
    created_at: Mon, 19 Mar 2018 00:33:57 UTC +00:00,
    updated_at: Mon, 19 Mar 2018 00:33:57 UTC +00:00,
    user_id: 1,
    mnemonic: "ah",
    sentences: ["hello", "world"]>


    [8] pry(main)> game.update(sentences: ['hello', 'world', 'again'])
    (0.2ms)  BEGIN
    User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
    SQL (0.4ms)  UPDATE "games" SET "updated_at" = $1, "sentences" = $2 WHERE "games"."id" = $3  [["updated_at", "2018-03-19 00:37:36.428710"], ["sentences", "{hello,world,again}"], ["id", 16]]
    (5.6ms)  COMMIT
    => true

    [10] pry(main)> game
    => #<Game:0x007ff420f750f0
    id: 16,
    hope: nil,
    wisdom: nil,
    created_at: Mon, 19 Mar 2018 00:33:57 UTC +00:00,
    updated_at: Mon, 19 Mar 2018 00:37:36 UTC +00:00,
    user_id: 1,
    mnemonic: "ah",
    sentences: ["hello", "world", "again"]>
    [11] pry(main)>

Please help? I apologize for the foolishness of the question, I just can't figure out what is going wrong.

1 Answers1

2

One issue appears to be that you don't actually have the :id in your permitted params, yet you are passing an id key in the provided examples.

For the sentences, try mapping the sentences key in your permitted params to an empty array:

def game_params
  params.require(:game).permit(:hope, :wisdom, :user_id, :mnemonic, sentences: [])
end

More information in this stack overflow comment: https://stackoverflow.com/a/16555975/2909095

Nitsew
  • 3,612
  • 1
  • 15
  • 20