Burak Özmen
Burak Özmen

Reputation: 873

Rails does not generate an authenticity token

I'm following these two tutorials altogether,

and implementing a simple comment system in Rails. However, I got a problem with handling the submit. I implemented a simple AJAX POST request to send my form data (as state). It looks like this:

var CommentForm = React.createClass({
    handleChange: function(e) {
    var name, obj;
    name = e.target.name;
    return this.setState((
      obj = {},
      obj["" + name] = e.target.value,
      obj
    ));
  },
    handleSubmit: function(e) {
        e.preventDefault();
        var author = React.findDOMNode(this.refs.author).value.trim();
        var text   = React.findDOMNode(this.refs.text).value.trim();
        if(!text || !author) {
            return;
        }
        $.post(this.props.postUrl, {comment: this.state}, null, "application/json");
        React.findDOMNode(this.refs.author).value = '';
        React.findDOMNode(this.refs.text).value = '';
    },
    render: function() {
        return (
            <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" name="author" onChange={this.handleChange} />
        <input type="text" placeholder="Say something..." ref="text" name="text" onChange={this.handleChange} />
        <input type="submit" value="Post" />
      </form>
        );
    }
});

As I examined the console, It looks like it is passing to the right route and the right params, except no authenticity_token param. Here is a screen shot of what is in the console.

enter image description here

In the first link that I've provided, it is said that jquery_ujs handles generating and passing an authenticity token to Ajax POST. However, this is not true in my case. What am I missing?

Edit: I've got a few answers that would fix my problem. However, I'm still curios about what makes the difference between my code and the code at this tutorial?

Upvotes: 2

Views: 1809

Answers (3)

Burak &#214;zmen
Burak &#214;zmen

Reputation: 873

Solved. Removed the line

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

from application.html.erb. It turns out that it was shadowing the jquery_rails while making an AJAX request.

Upvotes: 0

The Fabio
The Fabio

Reputation: 6260

You could add the authenticity_token attribute to your AJAX POST:

you could replace this line:

$.post(this.props.postUrl, {comment: this.state}, null, "application/json");

with this:

$.post(this.props.postUrl, {
    comment: this.state,
    authenticity_token: $('meta[name=csrf-token]').attr('content')
  }, null, "application/json");

Upvotes: 1

wiesion
wiesion

Reputation: 2455

This is because you are missing in your render method to pass an authenticity_token. Either you disable the authenticity check (not recommended), or you deliver your rendered form with an authenticity token.

In this case i would recommend to use Gon for clean passing of controller variables to JS: https://github.com/gazay/gon

When you installed it:

In your controller method:

gon.authenticity_token = form_authenticity_token

In your react class:

<form className="commentForm" onSubmit={this.handleSubmit}>
    <input type="hidden" name="authenticity_token" value={gon.authenticity_token}  />
    <input type="text" placeholder="Your name" ref="author" name="author" onChange={this.handleChange} />
    <input type="text" placeholder="Say something..." ref="text" name="text" onChange={this.handleChange} />
    <input type="submit" value="Post" />
</form>

Upvotes: 1

Related Questions