Search code examples
rubyruby-on-rails-4rubygemsdata-uriforestadmin

Forest Admin: "Invalid Data URI: nil" when i try to build a Import data custom action


I'm beginner in RoR and I would like to implement a custom action in forest admin for import data (csv). http://doc.forestadmin.com/developers-guide/#triggering-an-action-from-the-collection

I have my actions_controller (controllers/forest/actions_controller.rb):

class Forest::ActionsController < ForestLiana::ApplicationController
  require 'data_uri'
  def bulk_import
    uri = URI::Data.new(params.dig('data', 'attributes', 'values', 'file'))
    uri.data.force_encoding('utf-8')
    CSV.parse(uri.data).each do |row|
      Geo.create!({
        :departement=> row[0],
        :slug => row[1],
        :nom => row[2],
        :nom_simple => row[3],
     })
    end
    render json: { success: 'Data successfuly imported!' }
  end
end

My collection (lib/forest_liana/collections/geo.rb):

class Forest::Geo
  include ForestLiana::Collection
  collection :geos
  action 'bulk_import', global: true,
  fields: [{
    field: 'importer csv', type: 'File', isRequired: true, description: "Personal description",
  }]
end

And i add in my routes:

namespace :forest do
  post '/actions/bulk_import' => 'actions#bulk_import'
end

This doesn't work... :/

The message error:

Started OPTIONS "/forest/actions/bulk_import" for 127.0.0.1 at 2017-08-19 18:52:30 +0200
Started POST "/forest/actions/bulk_import" for 127.0.0.1 at 2017-08-19 18:52:30 +0200
Processing by Forest::ActionsController#bulk_import as HTML
  Parameters: {"data"=>{"attributes"=>{"ids"=>[], "values"=>{"importer csv"=>"data:text/csv;base64,77u/ZGVwYXJ0ZW1lbnQsIHNsdWcsIG5vbSwgbm9tX3NpbXBsZQ0iMSwiIjAxIiIsIiJvemFuIiIsIiJPWkFOIiIi"}, "collection_name"=>"geos"}, "type"=>"custom-action-requests"}}
Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.0ms)



URI::InvalidURIError - Invalid Data URI: nil:
  data_uri (0.1.0) lib/data_uri/uri.rb:15:in `initialize'
  app/controllers/forest/actions_controller.rb:4:in `bulk_import'

Solution

  • In your configuration, the field is named importer csv so it is this field name that will be sent in the request.

    In lib/forest_liana/collections/geo.rb

    class Forest::Geo
      include ForestLiana::Collection
      collection :geos
      action 'bulk_import', global: true,
      fields: [{
        field: 'importer csv', type: 'File', isRequired: true, description: "Personal description",
      }]
    end
    

    In your controller, you should do:

    uri = URI::Data.new(params.dig('data', 'attributes', 'values', 'importer csv'))
    

    Instead of :

    uri = URI::Data.new(params.dig('data', 'attributes', 'values', 'file'))
    

    It looks like importer csv should be the name of the action and not the field.

    If you want to name your action like this, here is the suitable configuration:

    class Forest::Geo
      include ForestLiana::Collection
      collection :geos
      action 'Importer CSV', global: true,
      fields: [{
        field: 'importer csv', type: 'File', isRequired: true, description: "Personal description",
      }]
    end