Search code examples
ruby-on-railsbackbone.jstypescriptbackbone-model

Backbone model.save() is causing OPTIONS not POST


I have a 'Create Account' view that I am starting to work on. Backbone 1.1.2 (typescript) front-end, Rails 4.2 beta 1 web service back-end.

Account Model

export class Account extends Backbone.Model {
    public urlRoot: string;
    public validation:any;

    constructor(attributes?: any, options?: any){
        this.urlRoot = 'http://domain.fake/accounts';
        this.validation = {
            email: {
                required: true,
                pattern: 'email'
            },
            password: {
                required: true,
                minLength: 6
            }
        };
        super(attributes, options);
    }
}

Create Account View:

export class CreateAccountView extends Backbone.View {
    public template: string;
    public events: any;
    public model: accountModelImport.Account;

    constructor(options?: Backbone.ViewOptions){
        this.el = '#modal';
        this.template = createAccountViewTemplate;
        this.model = new accountModelImport.Account();
        this.events = {
            'click #create-account-submit' : 'create'
        };
        super(options);
    }

    public render(): CreateAccountView {
        this.$el.html(_.template(this.template));
        Backbone.Validation.bind(this);
        this.$el.modal('show');
        return this;
    }

    public create(){
        var email:string = $('#create-account-email').val(), password:string = $('#create-account-password').val(), passconf:string = $('#create-account-password-confirmation').val();
        this.model.set({email: email, password: password, password_confirmation: passconf});
        this.model.save(null, {success: this.success, error: this.error});
    }

    public success(){
        alert('Success');
    }

    public error(){
        alert('error');
    }
}

Rails output on model.save() from above:

ActionController::RoutingError (No route matches [OPTIONS] "/accounts"):

I have seen many questions about what to pass as the first argument to .save() and I have tried them all with the same result each time: null, false, {}

I have tried searching for a question with the same issue but haven't been able to find one. I would like to try to get this to work natively before I go down the road of overriding the .sync() method.

Why is .save() trying to use OPTIONS instead of POST?


Solution

  • As pointed out by @meagar in his answer to this question this was not anything that backbone was trying to do wrong. It was a CORS issue. I had the headers set up manually using config.action_dispatch.default_headers.merge! but apparently that wasn't enough.

    A little more googling reveled this little gem of an answer to me (get it, 'gem')... Rails RoutingError (No route matches [OPTIONS]

    Which the answer there lead me to https://github.com/cyu/rack-cors

    After installing the gem and configuring per their instructions, the POST request went through as expected.

    Hope this helps others in the future, and be sure to give credit to @meagar for helping me down the right path.