ember.jsruby-on-rails-5fastjsonapi

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


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?


Solution

  • 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.