How to Load, Scan and Upload Files with Ruby on Rails

Have you ever thought about how to create a Web document scanning project with Ruby on Rails? In this tutorial, I’m going to guide you through how to create a Rails project with Dynamic Web TWAIN (DWT) SDK for loading, scanning and uploading document files step by step.

Prerequisites

Why not Ruby 2.2? You will see the following error when running the server because nokogiri does not support Ruby 2.2 on Windows.

nokogiri error in Ruby

For detailed information, please refer to GitHub.

Basic Steps of Creating Rails Project on Windows

  1. Install Rails with the command line:
    gem install rails
  2. Create an application:
    rails new dwt
  3. Change directory to dwt.
  4. Start the server:
    rails server
  5. Visit the default page on http://localhost:3000

Integrating DWT with Ruby on Rails

Create a controller:

rails generate controller twainscanning home

Copy Resources folder from < Dynamic Web TWAIN directory >\Resources to < Rails Project >\public\Resources.

Open < Rails Project >\app\views\twainscanning\home.html.erb and add following code:

<html>

<head>
  <title>DWT with Ruby</title>
  <script type="text/javascript" src="Resources/dynamsoft.webtwain.initiate.js"></script>
  <script type="text/javascript" src="Resources/dynamsoft.webtwain.config.js"></script>
  <style>
    h1 {
      font-size: 2em;
      font-weight: bold;
      color: #777777;
      text-align: center
    }
    table {
      margin: auto;
    }
  </style>
</head>

<body>
  <h1>
            DWT with Ruby
  </h1>
  <table>
    <tr>
      <td>
        <!-- dwtcontrolContainer is the default div id for Dynamic Web TWAIN control.
                   If you need to rename the id, you should also change the id in dynamsoft.webtwain.config.js accordingly. -->
        <div id="dwtcontrolContainer"></div>
      </td>
    </tr>

    <tr>
      <td>
        <input type="button" value="Load Image" onclick="btnLoad_onclick();" />
        <input type="button" value="Scan Image" onclick="AcquireImage();" />
        <input id="btnUpload" type="button" value="Upload Image" onclick="btnUpload_onclick()">
      </td>
    </tr>
  </table>

  <!--Custom script goes here-->
  <script type="text/javascript">
    Dynamsoft.WebTwainEnv.RegisterEvent('OnWebTwainReady', Dynamsoft_OnReady);
    var DWObject;

    function Dynamsoft_OnReady() {
      DWObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer'); // Get the Dynamic Web TWAIN object that is embeded in the div with id 'dwtcontrolContainer'
      DWObject.Width = 480; // Set the width of the Dynamic Web TWAIN Object
      DWObject.Height = 640; // Set the height of the Dynamic Web TWAIN Object
    }

    function btnLoad_onclick() {
      var OnSuccess = function() {};

      var OnFailure = function(errorCode, errorString) {};

      DWObject.IfShowFileDialog = true;
      DWObject.LoadImageEx("", EnumDWT_ImageType.IT_ALL, OnSuccess, OnFailure);
    }

    function AcquireImage() {
      if (DWObject) {
        DWObject.IfShowUI = false;
        DWObject.IfDisableSourceAfterAcquire = true; // Scanner source will be disabled/closed automatically after the scan.
        DWObject.SelectSource(); // Select a Data Source (a device like scanner) from the Data Source Manager.
        DWObject.OpenSource(); // Open the source. You can set resolution, pixel type, etc. after this method. Please refer to the sample 'Scan' -> 'Custom Scan' for more info.
        DWObject.AcquireImage(); // Acquire image(s) from the Data Source. Please NOTE this is a asynchronous method. In other words, it doesn't wait for the Data Source to come back.
      }
    }

    function btnUpload_onclick() {
      DWObject.HTTPPort = 3000;
      var CurrentPathName = unescape(location.pathname); // get current PathName in plain ASCII
      var CurrentPath = CurrentPathName.substring(0, CurrentPathName.lastIndexOf("/") + 1);
      var strActionPage = CurrentPath + "upload/";
      var strHostIP = "localhost"; // server IP e.g. 192.168.8.84

      var OnSuccess = function(httpResponse) {
        alert("Succesfully uploaded");
      };

      var OnFailure = function(errorCode, errorString, httpResponse) {
        alert(httpResponse);
      };

      var date = new Date();
      DWObject.HTTPUploadThroughPostEx(
        strHostIP,
        DWObject.CurrentImageIndexInBuffer,
        strActionPage,
        date.getTime() + ".jpg",
        1, // JPEG
        OnSuccess, OnFailure
      );
    }

  </script>

</body>

</html>

Open < Rails Project >\app\controller\application_controler.rb and comment out the following line:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  #protect_from_forgery with: :exception
end

Open < Rails Project >\config\routes.rb and add mappings:

Rails.application.routes.draw do
  get 'twainscanning/home'
  root 'twainscanning#home'
  post 'upload/' => 'twainscanning#upload'
end

Open < Rails Project >\app\controller\twainscanning_controller.rb and add following code for uploading images:

class TwainscanningController < ApplicationController
  def home
  end

  def upload
    uploaded_io = params[:RemoteFile]

    upload_dir = Rails.root.join('public', 'upload')
    unless Dir.exist?(upload_dir)
      Dir.mkdir(upload_dir)
    end

    File.open(Rails.root.join('public', 'upload', uploaded_io.original_filename), 'wb') do |file|
      file.write(uploaded_io.read)
    end

    respond_to do |format|
      format.html.any { render text: "Successfully uploaded!"}
    end

  end
end

Run server again:
 
Dynamic Web TWAIN with Ruby on Rails

Source Code

https://github.com/dynamsoftsamples/dwt-ruby-on-rails