Phil Hudson
Phil Hudson

Reputation: 3901

Sinatra PUT method not updating

My Sinatra method is receiving JSON correctly, but for some reason not saving it. It's being routed from Angular JS, so I'm wondering if one of the following could be the issue:

I've posted the code below, if you have any ideas as to why it's not working that would be fantastic.

Many thanks.

app.rb

#edit download
put '/view1/downloadedit' do
  @download = Download.get(1)  #1 for testing, will be downloadID
  data= JSON.parse(request.body.read)
  puts @download
  puts data
  if
    @download.update(data)
    status 201
    puts "edit saved okay"
  else
    status 201
    puts "edit failed to SAVE"
  end
end

controllers.js (Angular)

  // a scope function to edit a record
  $scope.updateinfo = function(downloadID) {
    id = downloadID
    var result = $scope.items.filter(function( items ) {
        return items.downloadID == id;
    });
    console.log(result);
    updatedata = $scope.items
    $http({
        method : 'PUT',
        url :  '/view1/downloadedit',
        data : result
    });
    $scope.loadData();
 };
}]);

Feedback from terminal showing correct JSON output from puts in app.rb

  angular connection working
  {"downloadID"=>1, "PageID"=>"1", "title"=>"nmnbm", "dlLink"=>"bnmnbm", "imgSrc"=>"mnbmnb", "caption"=>"aaa", "dlLive"=>1, "createdAt"=>nil}

Download class

#class download
class Download
include DataMapper::Resource
property :downloadID, Serial
property :PageID, String
property :title, String
property :dlLink, String
property :imgSrc, String
property :caption, String
property :dlLive, Integer
property :createdAt, DateTime
end

MySQL table structure for downloads, exported as CSV

<table_structure name="downloads">
    <field field="download_id" type="int(10) unsigned" null="NO" key="PRI" default="<null>" extra="auto_increment" />
    <field field="page_id" type="varchar(50)" null="YES" key="" default="<null>" extra="" />
    <field field="title" type="varchar(50)" null="YES" key="" default="<null>" extra="" />
    <field field="dl_link" type="varchar(50)" null="YES" key="" default="<null>" extra="" />
    <field field="img_src" type="varchar(50)" null="YES" key="" default="<null>" extra="" />
    <field field="caption" type="longtext" null="YES" key="" default="<null>" extra="" />
    <field field="dl_live" type="int(1)" null="YES" key="" default="<null>" extra="" />
    <field field="created_at" type="datetime" null="YES" key="" default="<null>" extra="" />

    <options name="downloads" engine="InnoDB" version="10" row_format="Compact" rows="8" avg_row_length="2048" data_length="16384" max_data_length="0" index_length="0" data_free="4194304" create_time="2013-11-04 17:26:56" update_time="<null>" collation="utf8_general_ci" create_options="" comment="" />
</table_structure>

Upvotes: 0

Views: 402

Answers (4)

Phil Hudson
Phil Hudson

Reputation: 3901

Needs to be passed the :id attribute to update.

put '/view1/downloadedit/:id' do
  data = JSON.parse(request.body.read)
  edit_id = data[0]["downloadID"]
  p data
  p edit_id
  @download_edit = Download.get(params[:id])
  p @download_edit
  success = @download_edit.update(:title => data[0]['title'],
                                  :caption => data[0]['caption'],
                                  :dlLink => data[0]['dlLink'],
                                  :imgSrc => data[0]['imgSrc'])
  if success
    status 201
    puts 'edit saved okay'
  else
    status 201
    puts 'edit failed to SAVE'
  end
end

Upvotes: 0

joews
joews

Reputation: 30330

I think the problem is that Datamapper does not know which property to use as the primary key. Try using this in your Download class:

property :downloadID, Serial, key: true

Upvotes: 1

Luke Byrne
Luke Byrne

Reputation: 119

Also your code

put '/view1/downloadedit' do
  puts 'angular connection working'
  ng_params = JSON.parse(request.body.read)
  puts ng_params
  @download = Download.update(ng_params)
end

should probably be

put '/view1/downloadedit' do
  # Below line shoudlnt be needed if the config.ru rack/parser works properly
  #ng_params = JSON.parse(request.body.read)

  @download = Download.where(id: params[:downloadID])

  # Maybe add an update! to blow up the update with validations to see if that is why data is not saving.
  unless @download.update(ng_params)
    return 'Error message'
  end
  @download
end

or something like that

Upvotes: 0

Luke Byrne
Luke Byrne

Reputation: 119

I ran into the same problem POSTing and PUTing JSON requests into sinatra.

I overcame it by adding this to my config.ru file. Got it from here

require 'rack/parser'

use Rack::Parser, content_types: {
  'application/json' => Proc.new { |body| ::MultiJson.decode body }
}

Upvotes: 0

Related Questions