Blog @ RohitRox

tips tricks tuts and everything learned

Rails Api Backed With Jwt

| Comments

Stand-alone client side applications, REST, API, JSON Web Token is all over the web. Last week I sat with one of my friend (Front-End Developer) to hack an Javascript MVC app with Rails-Api.

An awesome api, in the minds have following characterstics:

  • Excellent docs with success and failure sample response
  • A standard authorization mechanism
  • Consistent response body and codes

However, being an api developer in addition to that, I would like to have an automated tool that would help me to make sure that docs are always upto date with the api and I would like to use the latest and adopted authentication mechanism.

I would like to share my story of api development with Rails-api, Rspec, Rspec-api-documentation and JSON Web Token(JWT).

This is not a long tutorial about getting started with rails-devise-jwt, there is already lots of articles about what and why JWT and using JWT with ruby and rails. This is a blueprint of an end-to-end solution I adopted for development of an api.

The sample app is available here at github.

The commit in the speaks itself for steps that were done.

Ember Cli and Rails and Beyond

| Comments

Ember Cli and Rails Setup

Rails setup is pretty staright forward with rails new .. and new ember cli app with ember new .. but with following folder configuration

1
2
3
  | embercli-rails-app
  |-- rails  
  |-- ember

Inside of main project folder we’ll have a folder which will contain the rails code and another folder which will contain ember code only.

We would like to have coffeescript.

For coffeescript

1
  $ npm install --save-dev ember-cli-coffeescript

and renaming .js files to .coffee and correcting the js syntax to coffee will do the trick.

Make sure that ember app is all well by using ember server and visiting http://localhost:4200.

Before proceeding, it would be nice to have some tests.

Lets create a new test at ‘ember/tests/integration/home-page-test.coffee’.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  `import Ember from 'ember'`
  `import startApp from 'cli-app/tests/helpers/start-app'`
  `import Ember from 'ember'`

  App = null

  module 'Integration - Home Page',
    setup: ->
      App = startApp()
    ,
    teardown: ->
      Ember.run(App, 'destroy')

  test 'Should have Welcome test', ->
    visit('/').then ->
      equal(find('h2#title').text(), 'Welcome to Ember.js');

Visit http://localhost:4200/tests to run the tests.

Emberjs and Highcharts

| Comments

Let’s write a reusable ember view for rendering graphs and charts powered by highcharts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
App.HighChartsView = Ember.View.extend
  tagName: 'div'
  classNames: [ 'highcharts' ]
  chartConfig = {}

  setConfig: (type)->
    config = {
      chart:
        type: type
      title:
        text: @title || 'Highcharts'
      xAxis:
        categories: @dataset.categories || []
      yAxis:
          title:
            text: @yAxisTitle
      series: @series()
    }
    # Merge highcharts config if it is present
    Ember.merge(config, @highChartConfig) if @highChartConfig
    @set('chartConfig', config)

  series: ->
    @dataset.data

  prepareConfig: ->
    # if custom config is present then directly set it to chartConfig
    if @customHighChartConfig
      @set('chartConfig', @customHighChartConfig)
    else
      type = @type || 'line'
      @setConfig(type)

  didInsertElement: ->
    @prepareConfig()
    @renderHighchart()

  renderHighchart: ->
    @$().highcharts(@chartConfig)

Usage:

1
  {{ view App.HighChartsView dataset=dataset title="Sample Analytics" type="line" yAxisTitle='Temperature C' }}

Th dataset can be set at controller or may be at route.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  App.IndexController = Ember.ArrayController.extend
    dataset: {
      categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun','Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
      data: [{
                name: 'Tokyo',
                data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
            }, {
                name: 'New York',
                data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
            }, {
                name: 'Berlin',
                data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
            }, {
                name: 'London',
                data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
            }]
      }

Usage with control over config

1
  {{ view App.HighChartsView dataset=dataset highChartConfig=highChartConfig title="Sample Analytics" type="line" }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  App.IndexController = Ember.ArrayController.extend
    highChartConfig: {
      yAxis: {
        title: {
            text: 'Temperature (°C)'
        },
        plotLines: [{
            value: 0,
            width: 1,
            color: '#808080'
        }]
      },
      tooltip: {
          valueSuffix: '°C'
        }
      }

Hangman Game With Emberjs

| Comments

I built hangman game with emberjs, quick prevew. The game deals with more of view stuffs than other parts, I would like to share some thoughts and tricks I learned during the process.

hangman game with emberjs

I am not an ember expert so the way I have done may not be the optimal way of doing things in ember. Instead of walking through each steps, the code is well commented you can easily walk through, here I will describe striking stuffs.

Javascript Array Tricks

| Comments

JavaScript, at its base, is a very simple language. Due to burst of Js framework usage, in which many new developers jumps right into, there are very useful basic JavaScript techniques and tricks which many people are unaware of.

Today I want share some tricks with Javascript Arrays, which many developers are not using.

Cloning Array

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    var a = [1,2,3];
    var b = a;
    // bad
    // why

    a.pop();
    console.log(b);
    //=> [1,2]

    var b = a.slice(0);
    a.pop();
    console.log(b);
    //=> [1,2,4]
    // Good :-)

Single Table Inheritance in Mongoid

| Comments

Single table inheritance is a software pattern described by Martin Fowler. STI is basically an idea of using a single table(colection in case of mongo) to reflect multiple models that inherit from a base model.

We use STI pattern when we are dealing with classes that have same attributes and behaviour. Rather than duplicate the same code over and over, STI helps us to use a common base model and write specific behaviours in its inherited class while keeeping data on a same table.

Mongoid supports inheritance in both root and embedded documents. In scenarios where documents are inherited from their fields, relations, validations and scopes get copied down into their child documents, but not vice-versa.

A very simple example:

1
2
3
4
5
6
7
8
9
10
11
12
13
    class Employee
      include Mongoid::Document
      field :name, type: String
      field :employee_code, type: Integer
    end

    class FullTimeEmployee < Employee
      field status, type: String, default: "Temporary"
    end

    class InternEmployee < Employee
      field intern_period, type: Integer
    end

Up and Running Ruby on Rails on Ubuntu

| Comments

6 steps for setting ruby on rails development environment in Ubuntu.

Step 1: Setting up RVM

1
2
3
4
$ sudo apt-get update
$ sudo apt-get install curl
$ curl -L https://get.rvm.io | bash -s stable
$ source ~/.rvm/scripts/rvm

In order to work, RVM has some of its own dependancies that need to be installed. You can see what these are:

1
2
3
4
5
6
7
$ rvm requirements
# In the text that RVM shows you, look for this paragraph.
# Additional Dependencies:
# For ruby:
# apt-get --no-install-recommends install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev  libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev libgdbm-dev ncurses-dev automake libtool bison subversion pkg-config libffi-dev
# Just follow the instructions to get your system up to date with all of the required dependancies.
$ sudo apt-get --no-install-recommends install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev libgdbm-dev ncurses-dev automake libtool bison subversion pkg-config libffi-dev

Then

1
2
3
$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" >> ~/.bash_profile
# or 
$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" >> ~/.bashrc

Step 2: Install ruby

1
2
3
4
5
6
$ rvm install 1.9.3
# after success you can verify your installation by 
$ rvm list
# should output something like 
# rvm rubies
# =* ruby-1.9.3-p362 [ i686 ]

Step 3: RubyGems

1
$ rvm rubygems current

Step 4: Rails

1
2
3
4
5
6
7
# a Javascript runtime, NodeJs
$ sudo add-apt-repository ppa:chris-lea/node.js
$ sudo apt-get update
$ sudo apt-get install nodejs

$ gem install bundler
$ gem install rails

Step 5: First Rails app

1
2
3
4
5
6
$ rails new my_app
$ cd my_app
$ bundle install
$ rails s
# open browser and visit localhost:3000
# you should see the famous welcome abroad page

Step 6: Development Extras

Sublime Text 2

1
2
3
$ sudo add-apt-repository ppa:webupd8team/sublime-text-2
$ sudo apt-get update
$ sudo apt-get install sublime-text

Install sublime package manager from here for other sublime goodies.

Configure Vim for Rails

1
$ curl -Lo- https://bit.ly/janus-bootstrap | bash

Get Selected Text From Web Page

| Comments

This is a quick tip you can use for getting the selected text from your webpage.

1
2
3
4
<p>I am not selectable. You can test.</p>
<div id="here">
    How about selecting me. Try me.
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(document).ready(function() {

    function getSelectedText(){
        var text = "";
        if (window.getSelection) {
            text = window.getSelection();
        } else if (document.getSelection) {
            text = document.getSelection();
        } else if (document.selection) {
            text = document.selection.createRange().text;
        }
        return text;
    }

    $('#here').bind("mouseup", function(){
        alert(getSelectedText());
    });

});

Lets Learn to Knockout

| Comments

Knockout.js is known for rapid and responsive UI development. Lets try it to build something today. Lets see quick demo of what we are going to build.

Download Source

This is a basic table that is used in bills or receipts. We will try to add some magic to table like autocomplete, automatic information fill up of selected item and calculation of amounts with the help of knockout.

I will not describe what knockout.js is and why use it. Learn.knockout.js has an excellent tutorial for knockout js beginners. I strongly suggest to go through learn.knockoutjs.com before proceeding.

I assume basic understanding of knockout js from here.

Let’s setup the files first. Nothing fancy, I have just used jquery source file and knockout source js from their official websites and I have used twitter bootstrap prettifying stuffs.

I have initial table markup, which looks like as shown below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
   <div class="container">
      <div class="row">
        <div class="span12">
          <table class="table table-bordered">
            <thead>
              <tr>
                <th>Item</th>
                <th>Description</th>
                <th>Unit Price</th>
                <th>Quantity</th>
                <th>Amount</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td><input class="span3"  /></td>
                <td><input class="span4" /></td>
                <td><input class="span1" /></td>
                <td><input class="span1" /></td>
                <td><input class="span1" /></td>
                <td><button class="btn">Remove</button></td>
              </tr>
            </tbody>
          </table>
          <p class="pull-left">
            <button class="btn">Add New Row</button>
            <button class="btn">Save</button>
          </p>
          <h4 class="pull-right">
            <strong>Grand Total: <span></span> </strong>
          </h4>
        </div>
      </div>
    </div>

Lets see what we have upto here and talk something about what we are trying to do to this table.

knockout table 1

Lets summarize the behaviours we would like to have:

  • Add a new row
  • Suggest items in item field
  • Fill up the item information (description and price) automatically
  • Calculate the grand total as items are added
  • A remove button to remove item and re-compute grand total automatically on removal

Canvas Images and Rails

| Comments

With the introduction of Canvas, HTML5 has empower us to draw shapes, graphs, render texts, make gradients and patterns, manipulate images pixels, set an animations, even creating a stunning games! All this stuffs occur on the client side in the browsers. So let say you make an app that render some effects in a Canvas element and you want to allow user to take screenshot of the resut or save the result in your server for yourself.

Let’s digg how can we do it and save that canvas as an image in ther server using Rails.

Strategy 1 : Send canvas image as raw dataURL

The data URI scheme is a URI scheme that provides a way to include data in-line in web pages as if they were external resources. The canvas.toDataURL() method returns the image data of the canvas as Data URI. And the Data URI has the image data Encodes with MIME base64.

Let’s see how it works. Copy and run this javascript snippet in your browser console. Somewhere at the bottom of the page you’ll see a green circle.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;

context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();

document.body.appendChild(canvas)

Now lets render that canvas as an image.

1
2
var dataURL =  canvas.toDataURL('image/png');
window.location = dataURL;