SnareChops
SnareChops

Reputation: 13347

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?

Upvotes: 0

Views: 180

Answers (2)

SnareChops
SnareChops

Reputation: 13347

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.

Upvotes: 0

user229044
user229044

Reputation: 239240

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

It's not. This is the CORS "preflight request" at work. If the OPTIONS request is successful, the POST request will follow.

...The preflight request is made as an HTTP OPTIONS request (so be sure your server is able to respond to this method). It also contains a few additional headers:

Access-Control-Request-Method - The HTTP method of the actual request. This request header is always included, even if the HTTP method is a simple HTTP method as defined earlier (GET, POST, HEAD).

Access-Control-Request-Headers - A comma-delimited list of non-simple headers that are included in the request.

The preflight request is a way of asking permissions for the actual request, before making the actual request. The server should inspect the two headers above to verify that both the HTTP method and the requested headers are valid and accepted.

See http://www.html5rocks.com/en/tutorials/cors/

Upvotes: 3

Related Questions