3

I'm very new to Rails and web development.

I'm generating a bunch of objects in Matlab and I'd like send these objects to a database in my Rails app. Can anyone advise me on how to do this?

So far, on the Rails end, I've generated basic scaffolding for my data. I can add objects to my database using a form at '/myobjects/new'.

On the Matlab end, I've been trying to add objects using HTTP POST requests, like so:

s = urlread('http://localhost:3000/myobjects.json','POST',{'myobject','{name1:''value1''}'})

This fails and prints the following to the Rails console:

Started POST "/myobjects.json" for 127.0.0.1 at 2012-06-16 11:48:28 -0400
Processing by MyobjectsController#create as JSON
  Parameters: {"myobject"=>"{name1:'value1'}"}
WARNING: Can't verify CSRF token authenticity
Completed 500 Internal Server Error in 1ms

NoMethodError (undefined method `stringify_keys' for "{name1:'value1'}":String):
  app/controllers/myobjects_controller.rb:43:in `new'
  app/controllers/myobjects_controller.rb:43:in `create'

This approach might be way off base, but hopefully the code above makes my goal clear. Can anyone tell me how to fix my code, or suggest a better strategy for getting my data into rails?

EDIT

At the moment my new and create methods look like this (but I can change them as required)

# GET /irs/new
  # GET /irs/new.json
  def new
    @ir = Ir.new

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

  # POST /irs
  # POST /irs.json
  def create
    @ir = Ir.new(params[:ir])

    respond_to do |format|
      if @ir.save
       format.html { redirect_to @ir, notice: 'Ir was successfully created.' }
       format.json { render json: @ir, status: :created, location: @ir }
      else
        format.html { render action: "new" }
        format.json { render json: @ir.errors, status: :unprocessable_entity }
      end
    end
  end
Amro
  • 123,847
  • 25
  • 243
  • 454
dB'
  • 7,838
  • 15
  • 58
  • 101
  • 1
    Can you post the new and create action your posting to? – Noah Clark Jun 16 '12 at 16:12
  • Ok, see edit above. Is that the info you were looking for? – dB' Jun 16 '12 at 16:25
  • Maybe use sprintf to create the name1: value1 pair and then send that string in? – Ansari Jun 16 '12 at 16:27
  • @Ansari Thanks, but no dice. Did this in Matlab `s = urlread('http://localhost:3000/irs.json','POST',{'ir',sprintf('{%s:%s}','field1','value1')})` and got this `NoMethodError (undefined method ``stringify_keys' for "{field1:value1}":String)` – dB' Jun 16 '12 at 16:43
  • JSON isn't my strong suit, but I think you have to enclose them in single or double quotes. So try '{"%s":"%s"}' instead. – Ansari Jun 16 '12 at 16:45
  • @dB': I might be wrong, but doesn't JSON use double-quoted strings. Try the following request from MATLAB: `s = urlread('http://localhost:3000/myobjects.json','POST',{'myobject','{"name1":"value1"}'})` – Amro Jun 16 '12 at 16:45

2 Answers2

3

In the end I gave up trying to do this with matlab's built-in functions. Instead, I imported a Java library (Apache HttpComponents). Here's the script I came up with. This did the job.

javaaddpath(['utils/httpcomponents-client-4.2/lib/httpcore-4.2.jar']);
javaaddpath(['utils/httpcomponents-client-4.2/lib/httpclient-4.2.jar']);


import org.apache.http.impl.client.DefaultHttpClient
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.StringEntity


httpclient = DefaultHttpClient();

httppost = HttpPost('http://127.0.0.1:3000/myobjects.json');
httppost.addHeader('Content-Type','application/json');
httppost.addHeader('Accept','application/json');

params = StringEntity('{"field1":"value1"}');
httppost.setEntity(params);

response = httpclient.execute(httppost);
dB'
  • 7,838
  • 15
  • 58
  • 101
1

You can avoid that specific problem by setting

class MyobjectsController < ApplicationController
  protect_from_forgery :except => :create
  ...
end

within your controller. It disables the CSRF token validity check.

moritz
  • 25,477
  • 3
  • 41
  • 36
  • Ok, this addition got rid of the CSRF warning but it didn't solve my problem. I still get the NoMethodError and can't add objects to the database. Thanks all the same though. – dB' Jun 16 '12 at 16:10
  • Ok, I'm sorry. The problem is that you are transmitting `{'myobject','{name1:''value1''}'}`. Does Matlab support sending it like this: `{'myobject',{ 'name1', 'value1'}}`? – moritz Jun 16 '12 at 16:14
  • Yeah, I can do that, but I still get basically the same NoMethodError. `"{name1:'value1'}":String` just becomes `"{'name1','value1'}":String` – dB' Jun 16 '12 at 16:21
  • You could `params[:ir] = JSON.parse(params[:ir])` before the Ir.new call (With the hash sent as you did orgiginally). – moritz Jun 16 '12 at 16:30
  • Hmm... tried that and I get a parser error: `JSON::ParserError (757: unexpected token at '{field1:'value1'}'): app/controllers/irs_controller.rb:50:in 'create' ` – dB' Jun 16 '12 at 16:38
  • That's because `{field1:'value'}` isn't valid JSON as far as the parser is concerned. `field1` needs to be escaped by quotes. – Ron Jun 16 '12 at 18:35