Rails ActionController::ParameterMissing error when creating new record in Ember

255 views Asked by At

Rails 5.2 with fast_jsonapi 1.5, Ember 3.4

I create a new Tag record like this in Ember:

let newTag = this.get('store').createRecord('tag', {
  name: this.get('name')
});
newTag.save();

This sends the following json (as seen in the Network tab of Chrome as the Request Payload):

{"data":{"attributes":{"name":"photos","created_at":null,"updated_at":null},"type":"tags"}}

But Rails only gets (as verified by printing out the params in the create method of the TagsController):

{"controller"=>"tags", "action"=>"create"}

And it throws the following error:

ActionController::ParameterMissing (param is missing or the value is empty: tag)

And here is my controller code:

# app/controllers/tags_controller.rb
class TagsController < ApplicationController
  def create
    tag = Tag.create!(tag_params)
    render json: {status: "success"}
  end

  private

  def tag_params
    puts params
    params.require(:tag).permit(:name)
  end
end

What's the trick to get ember and rails to understand each other? Since ember is sending the "type" in the payload, can I get Rails to understand that this is the model and thus fulfill the requirement I've set that "tag" be present in the params?

2

There are 2 answers

0
wetjosh On BEST ANSWER

After rereading the action controller overview I learned I had to include the 'Content-Type': 'application/json' header in my request. I accomplished this by customizing my application adapter in Ember:

// app/adapters/application.js

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
  init() {
    this._super(...arguments);
    this.set('headers', {
      'Content-Type': 'application/json'
    });
  }
});

The next problem I had to deal with was changing my use of strong parameters in the Rails controller:

# app/controllers/tags_controller.rb

def tag_params
  params.require(:data).require(:attributes).permit(:name)
end

Hope this helps someone else.

0
Almokhtar On

in ember 3.26 you can do like this :

export default class ApplicationAdapter extends JSONAPIAdapter {
headers = {
  'Content-Type': 'application/json'
}

instead of

export default DS.JSONAPIAdapter.extend({
init() {
this._super(...arguments);
this.set('headers', {
  'Content-Type': 'application/json'
});