3. Adding other CRUD operations with Ruby on Rails

Description

In this article the code will be refactored from the previous sample (Adding simple criteria, sorting and data paging), the correct filtering functions will be implemented for the text columns and additional functionality will be added to have a fully working DataSource implementation.

Set up DataSource to be loadable by the server

In the previous sample, filtering by a text value would not select rows which contained the filter term, only those that were specifically equal to it. To correctly filter by a text value, it is necessary to identify which columns are of type text and which are other types. To achieve this, the declaration of the DataSource needs to be moved to a separate file, which will be loaded on both the client and server side. 

Firstly, create a new folder, called 'datasource' in the /app/assets/javascripts directory.  In this folder, create a javascript file which defines the DataSource itself. Give this file the same name as the ID of the DataSource.

/app/assets/javascripts/datasource
isc.RestDataSource.create({
    "ID": "suppyItem",
    "fields":[
        {"name":"itemID", "type":"sequence", "hidden":"true", "primaryKey":"true"},
        {"name":"itemName", "type":"text", "title":"Item", "length":"128", "required":"true"},
        {"name":"SKU", "type":"text", "title":"SKU", "length":"10", "required":"true"},
        {"name":"description", "type":"text", "title":"Description", "length":"2000"},
        {"name":"category", "type":"text", "title":"Category", "length":"128", "required":"true" },
        {"name":"units", "type":"enum", "title":"Units", "length":"5",
            "valueMap":["Roll", "Ea", "Pkt", "Set", "Tube", "Pad", "Ream", "Tin", "Bag", "Ctn", "Box"]
        },
        {"name":"unitCost", "type":"float", "title":"Unit Cost",
            "validators":[
                {"type":"floatRange", "min":"0", "errorMessage":"Please enter a valid (positive) cost"},
                {"type":"floatPrecision", "precision":"2", "errorMessage":"The maximum allowed precision is 2"}
            ]
        },
 
        {"name":"inStock", "type":"boolean", "title":"In Stock"},
        {"name":"nextShipment", "type":"date", "title":"Next Shipment"}
    ],
    "criteriaPolicy":"dropOnChange",
    "dataFormat":"json",
    "operationBindings": [
                { "operationType": "fetch", "dataProtocol": "postMessage", "dataURL": "/smartclient/data" },                
                { "operationType": "add", "dataProtocol": "postMessage", "dataURL": "/smartclient/data" },
                { "operationType": "update", "dataProtocol": "postMessage", "dataURL": "/smartclient/data" },
                { "operationType": "remove", "dataProtocol": "postMessage", "dataURL": "/smartclient/data" }
            ] 
});

And create the javascript file for the ui, called 'smartclient_ui.js' in the /app/assets/javascripts directory and add ui controls.

/app/assets/javascript/smartclient_ui.js
isc.ListGrid.create({
    ID: "suppyItem",
    width: 700,
    height: 224, 
    alternateRecordStyles: true,
    dataSource: suppyItem,
    showFilterEditor: true,
    autoFetchData: true,
    dataPageSize: 20,
    canEdit:true,
    canRemoveRecords:true
});
isc.IButton.create({
    top: 250,
    title: "Edit New",
    click: "suppyItem.startEditingNew()"
});

Now, modify the view file for the application to load this additional DataSource. You should edit the 'app/views/smartclient/index.html' file and change it's content to:

Error rendering macro 'code': Invalid value specified for parameter 'firstline'
<%= javascript_include_tag "datasource/supplyitem" %>
<%= javascript_include_tag "smartclient_ui" %>

Change the Gemfile 

The smartclient gem v 0.0.4 supports the RPCManager helper class, the developer can handle the request with the RPCManager class easily.  You can get the methods from here or you can modify and add another methods after you build the gem from github.

Gemfile
gem "smartclient", "~> 0.0.4"


Then run the bundle command on the console:

bundle install

Now you can use the RPCManager helper class. 

Processing the Request in the Controller.

It's easy to use the RPCManager class. After you got the request post parameters,  the processRequest method will process everything according to the request.

app/controllers/smartclient_controller.rb
require 'RPCManager'
class SmartclientController < ApplicationController         
    def index
      
    end
    
    def data 
      # set the request parameters
      rpc = RPCManager.new(params, Supplyitem)      
      @result = rpc.processRequest 
      render json: @result
    end   
end 

As you see, the constructor of the RPCManager has two parameters, the first parameter is the request, and the second parameter is the model for the DataSource,  it will be processed as the object, you should define the model class which maps to the datasource table in the database(In the previous article, we already defined).

Please don't forget to add the filter method in the model, the RPCManager helper class will parse this method after the model object is got via the second parameter.

By running rails server command, the application will start and a grid fetching and displaying the rows found in the table will be shown. (http://localhost:3000)

rails s

The complete code for this sample project can be downloaded from github.