1

I am trying to learn how to post some data using $.ajax through jquery to a simple rails scaffold project. There is one standard scaffold created controller => Images

class ImagesController < ApplicationController
  # GET /images
  # GET /images.json
  def index
    @images = Image.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @images }
    end
  end

  # GET /images/1
  # GET /images/1.json 
  def show
    @image = Image.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @image }
    end
  end

  # GET /images/new
  # GET /images/new.json
  def new
    @image = Image.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @image }
    end
  end

  # GET /images/1/edit
  def edit
    @image = Image.find(params[:id])
  end

  # POST /images
  # POST /images.json
  def create
    @image = Image.new(params[:image])

    respond_to do |format|
      if @image.save
        format.html { redirect_to @image, notice: 'Image was successfully created.' }
        format.json { render json: @image, status: :created, location: @image }
      else
        format.html { render action: "new" }
        format.json { render json: @image.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /images/1
  # PUT /images/1.json
  def update
    @image = Image.find(params[:id])

    respond_to do |format|
      if @image.update_attributes(params[:image])
        format.html { redirect_to @image, notice: 'Image was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @image.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /images/1
  # DELETE /images/1.json
  def destroy
    @image = Image.find(params[:id])
    @image.destroy

    respond_to do |format|
      format.html { redirect_to images_url }
      format.json { head :no_content }
    end
  end
end

with one route => resources :images. The database schema consists of one field => t.string :name. My initial test html file is:

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js">    </script>
</head>
<body>
    <script>
    $(document).ready(function(){
        $.ajax({
            type: 'POST', url: "localhost:3000/images",
            data: { name: "johngalt" }
        });
    });
    </script>
</body>

The result from webrick is:

Started POST "/images" for 127.0.0.1 at 2012-04-17 09:50:19 -0500
Processing by ImagesController#create as */*
  Parameters: {"name"=>"johngalt"}
WARNING: Can't verify CSRF token authenticity
   (0.1ms)  begin transaction
   SQL (63.5ms)  INSERT INTO "images" ("created_at", "name", "updated_at") VALUES (?, ?,  ?)  [["created_at", Tue, 17 Apr 2012 14:50:21 UTC +00:00], ["name", nil], ["updated_at",  Tue, 17 Apr 2012 14:50:21 UTC +00:00]]
   (2.0ms)  commit transaction
 Redirected to http://localhost:3000/images/7
 Completed 302 Found in 81ms (ActiveRecord: 65.6ms)

I'm not sure why name doesn't contain "johngalt". Does this have something to do with the " WARNING: Can't verify CSRF token authenticity"?

Edit When I use curl:

curl -d "image[name]=johngalt"  localhost:3000/images.json

The record is created and the name field contains "johngalt". In essence, I'm trying to figure out the .ajax equivalent of doing what I was able to do in curl?

JohnGalt
  • 2,851
  • 2
  • 21
  • 29

1 Answers1

0

The CSRF token is automatically added in your post forms when you use the Rails form_for helper to create a form, and is meant to protect users against cross-site request forgery attacks. So, if you are trying to post in a javascript file you won't have access to the token.

You can disable CSRF token authentication for specific actions if you so wish, as long as you understand the consequences.

There are a few ways you can do that, listed here: Turn off CSRF token in rails 3

Edit Looking at your CURL example, it looks like you are ajax posting the wrong data. You are ommiting the 'image' param namespace. Try:

<script>
$(document).ready(function(){
    $.ajax({
        type: 'POST', url: "localhost:3000/images",
        data: { image: { name: "johngalt" } }
    });
});
</script>
Community
  • 1
  • 1
Achilles
  • 766
  • 4
  • 13
  • Is the CSRF token issue, preventing the value => "johngalt" from being updated in the field => name? – JohnGalt Apr 17 '12 at 15:09
  • Your problem is that you need to post `data: {image : { name: "johngalt" }}`, like you did in your curl request – Achilles Apr 17 '12 at 16:37
  • That allowed the field to uploaded thank you. Does this error, XMLHttpRequest cannot load http://localhost:3000/images.json. Origin null is not allowed by Access-Control-Allow-Origin, revolve around the cross domain issue? – JohnGalt Apr 17 '12 at 16:52
  • Sounds like it. Try sticking this in your controller to see what happens: `skip_before_filter :verify_authenticity_token` – Achilles Apr 17 '12 at 16:55
  • Thank you for replying but that didn't fix it. – JohnGalt Apr 18 '12 at 14:40
  • Not really enough info to go on. Maybe this is pertinent? http://madhukaudantha.blogspot.de/2011/05/access-control-allow-origin-in-rails.html – Achilles Apr 18 '12 at 14:46