to_json vs as_json in Rails API

Recently we have been working on Rails API. During that time, we were curious about the difference between as_json and to_json. In this article, we are sharing the difference we learned.

to_json in Rails API

Let’s discuss how we started out building our APIs using ‘to_json’. to_json will return JSON string representing the hash. Option are passed to each element.

In to_json without any option,  the returned JSON string will include all the model attributes

to_json had some great options of ActiveRecord objects. We could just tell the method to only render certain attributes, or to include association or method calls. We had:

  • only – Only show column names in the output as specified in the list
  • except – Show all column names except the ones specified in the list

to_json works fine and seamlessly ok, as long as the database schema is deeply coupled with the API output.When it takes the next level where we want to render a certain attribute in json it start to break.

This will start to generate a bit load to controllers. Such methods of generating json don’t feel quite right and begin to break down. This is because the to_json is interested in ‘serializing’ a database object while most of the developers try to put relevant representation for their API.

Anytime to_json is called on an object, as_json is invoked to create the data structure, and then that hash is encoded as a JSON string using ActiveSupport::json.encode. This happens for all types: Object, Numeric, Data, String etc.

Now the creation of the json is separated from the rendering of the json.  as_json is used to create the structure of the json as a Hash, and the rendering of that hash into JSON string is left up-to ActiveSupport::json.encode.

as_json in Rails API

as_json Returns a hash representing the model. Like in to_json, option are passed to each …

Read More

Setup your rails application with one command

Generally setting up a rails app is running some same set of commands, for example installing gem, creating database, loading schema and start rails server.

We can create a script and run it to setup our application since Rails 4.2 a bin/setup file is generated by default.

Here is the example of setup script.

Setup script sets your rails application for development environment instantly.  This is helpful when a new developer trying to set up your application or when setting up an application on a new machine. We should keep the setup script updated.

Let’s understand the setup script step by step and modify according to our requirements.

First setup basic required library and path of our application in APP_ROOT

Now system! method here execute the commands passed to it and shows the backtrace of error in case of command fails.

system will execute the given rails command and abort will stop script execution and will show us the backtrace of failed command, we can modify it if we don’t want to stop the execution of the script and get some custom error messages.

In the below snippet of the script, we are going to our application root and performing operations.

To create config file if not already exist, modify your script as

Read More

Authorization with Pundit gem

Security is an important aspect of application development. Two main components of security are Authentication (Who are you?) and Authorization (are you supposed to be here?). Authentication verifies the user’s identity while authorization verifies whether that user has access rights on certain resources to perform actions on them.

Two popular gems for authorization in the rails world are CanCanCan and Pundit, we at Red Panthers prefers pundit over CanCanCan we get to write Pure Ruby Objects and keep the logic for each part separate.

The gem CanCanCan isolates (encourages) all authorization logic into a single class. It is a drawback when the complexity of application increases. Pundit gem provides object oriented design patterns to build our own authorization system that meets project’s requirements. It enables us to keep the models and controllers free from authorization code and allows to keep the resource logic separately. This flexibility and simplicity of Pundit gem help to use it with ease.

To start with Pundit

Add Pundit gem to your gem file and run bundle install.

Integrate Pundit to Rails application by adding the following line to ApplicationController.

If you run the Pundit’s generator as below, it will generate app/policies folder which contains application_policy.rb by default.

Then restart the Rails server.

Base class policy looks like

Create policies

Policy classes are the core of Pundit. In the app/policies folder, we can write our own policies. Each policy is a Ruby class. Each policy class should be named after a model they belong to, followed by the word Policy. For example, use CollectionPolicy for Collection model. Pundit can also be used without an associated model.

Pundit uses the current_user method to get the first argument in initialize method in ApplicationPolicy. But if current_user is not the method that should be invoked by Pundit, simply define a method in your controller.

Logically, Pundit can be used outside controllers, for …

Read More

Deploying Rails application on AWS, using Nginx, Puma and Mina

In this tutorial we are going to setup an AWS EC2 instance for deployment of rails application.

Server Setup

Following is the setup instruction for ubuntu 16.04 using ruby 2.4, Postgres 9.6 and rails 5.

Installing Ruby

Setting up dependencies for ruby.

Next step is to install ruby using RVM.

Last step is to install bundler.

Installing Rails

Installing NodeJS, this lets you use Coffee script and the Asset Pipeline in Rails which combines and minifies your javascript to provide a faster production environment.

Next is to install rails.

You can verify the installation of rails version.

Installing PostgreSQL

The postgres installation doesn’t setup a user for you, so you’ll need to follow these steps to create a user with permission to create databases.

Install Nginx

Following are some basic commands to manage Nginx:

Nginx Configuration

First disable default site by removing the symlink.

Now create a new virtual host config file.

edit the my_app.conf file:

Puma Configuration

Change config/puma.config file according to following example:

Create puma upstart script

Let’s create an Upstart init script so we can easily start and stop Puma.

Now open the provided puma.conf file, so we can configure the Puma deployment user.

Look for the two lines that specify setuid and setgid, and replace “apps” with the name of your deployment user and group.

Now copy the scripts to the Upstart services directory.

The puma-manager.conf script references /etc/puma.conf for the applications that it should manage. Let’s create and edit that inventory file now.

Each line in this file should be the path to an application that you want puma-manager to manage. Add the path to your application now. For example.

Jungle upstart script provides following commands to manage puma app server:

Install Mina

Add in your Gemfile.

and run bundle install to install mina.

Create deployment script

It will create config/deploy.rb, let’s edit it as following:

Now to setup directory structure run:

To deploy the application run:

 

REFERENCES:

https://gorails.com/setup/ubuntu/16.04

https://github.com/mina-deploy/mina

https://github.com/puma/puma

 

Read More

[Tip] Mina: Find last git commit released

A project that we were handling hadn’t had a deployment in some time. So we were confused on what all commits were going to go to production ( bad karma for us for not keeping a release or change log). We use mina for all our deployment as we found it to be faster that Capistrano. So we were sure that there would be something on our server to help us settle this dilemma. We finally solved this by going through the various folders and files.

Edit the file inside the file with your branch name located at /path/to/project/scm/refs/heads. Like for example if you have your project in /var/www folder and you are deploying master then you should edit the file called master found at the following location./var/www/project/scm/refs/heads/master that file would have only one line and that’s the last git commit released.

 

Read More

Taking screenshots of webpages using Ruby

Recently we have been working on taking screenshots for web page while generating reports based on that website. During this endeavor, we came across some tools to achieve that. We are sharing the information we gathered here.

The tools that we will discuss for screencapture, in  Ruby,  are:

  • PhantomJS
  • Screencap gem
  • Webshot gem

Screencap and webshot are gems in Ruby that depends on a tool called PhantomJS. It is basically a web browser without a user interface, primarily used for testing websites. Such type of browsers are generally referred to as headless browsers,

Screenshots with PhantomJS

PhantomJS is quite easy to install and is multiplatform, available on major operating systems.

To start, our script must require a reference to the webpage module then use it to create an instance:

Use the instance.open() method and pass it the arguments, the url of the webpage that we want to capture screenshot.

instance.render() method captures the screenshot and saves it to the file specified in the argument.
Run the script as,

Screenshot is saved in the  directory where we run the script.

Now what we have above is all JavaScript, but to use the phantom JS in our rails application we have gems that provide us with an easy interface to acheive the same.

Screencap gem

The gem ‘screencap’ is introduced in Ruby to make screenshot capture easy. However, the gem depends on  ‘PhantomJS’, so we need to have PhantomJS installed on machine to capture screenshots with screencap gem.
But screencap does not work with PhantomJS 2.1.1, which is the latest version.
So we need to install version 1.9.8

check version

To install screencap gem in your application, add this line to gemfile

Or install it as

Usage

To capture screenshot with screencap

  • Fetcher class accepts url of the website to take screenshot.
  • Screenshot is taken when fetch method is called.
  • Also, fetch method supports various optional parameters to specify the area to capture the screenshot.
  • We can specify where to store the …
Read More

Difference between Date, Time and DateTime

Date and time are one of the most important aspects which every coder has to deal with in Ruby. Well, let’s get to know how we keep it up alive and functional.
There are 3 different classes in Ruby that handles date and time. They are Date, Time and DateTime. Date and DateTime classes are both from date library. And Time class from its own time library.

In this article we’ll see how Date and Time works. Let’s have a look at each one of them.

Date

When you need a string format of year, month and day, you have to go through Date class.

  • Has date attributes only (year, month, day)
  • Based on integer whole-day intervals from an arbitrary “day zero”
  • Can handle date arithmetic in units of whole days
  • Date object is created with ::new, ::jd, ::ordinal, ::commercial, ::parse, ::strptime, ::today, Time#to_date etc.
  • Takes 4 bytes to store.

Eg:

Time

If you need both date and time values, we can make use of Time class.

  • Has date and time attributes (year, month, day, hour, min, sec, subsec)
  • Can handle negative times before unix time
  • Can handle time arithmetic in units of seconds

Eg:

Also rails provide a really good time class called ActiveSupport::TimeWithZone. It contains all the features the Time class have, plus many improvements, such as the support for configurable time zones.

DateTime

  • Has date and time attributes (year, month, day, hour, min, sec)
  • It  is formatted as YYYY-MM-DD HH:MM:SS
  • Based on fractions of whole-day intervals from an arbitrary “day zero” (-4712-01-01)
  • Can handle date arithmetic in units of whole days or fractions
  • Takes 8 bytes to store, and has a precision of .001 seconds.
    • A four-byte integer packed as YYYY×10000 + MM×100 + DD
    • A four-byte integer packed as HH×10000 + MM×100 + SS
  • Valid ranges go from the year 1000 to the year 9999
  • It is created with ::new, ::jd, ::ordinal, ::commercial, ::parse, ::strptime, ::now, Time#to_datetime etc.

Eg:

Let’s see the Differences among all of them which makes …

Read More

Enumerator: When to Use and Why are they so special?

In this post, we’ll take a look at the basics of Enumerator, When to use it and Why they are so special. So let’s begin!

As the name implies Enumerator is used for iterating over a collection of items. It allows both internal and external iteration.

So how do we Create an Enumerator?

There are 3 different ways to create it. They are from,

  • A Block,
  • An Enumerable,
  • A Blockless Enumerable Method Call.

Let’s have a look on each of the method now.

From a Block

We can create an enum by passing a block to its constructor. A yielder object will be passed to this block. The yielder’s #<< method can be used to define the elements. Enumerator#next can then be used to provide iteration.

Eg:

From an Enumerable

The most common way to create an Enumerator is from an Enumerable object, specifically, an object that defines a #each method. Object#to_enum is implemented to return a new Enumerator which will enumerate by sending #each to its receiver.

Eg:

From a Blockless Enumerable Method Call

There are several Enumerable methods that take a block and returns an Enumerator when called without a block. For instance, calling Array#select without a block will return an Enumerator with an #each method that will filter like #select.These blockless calls offer a concise alternative to Object#to_enum.

Eg:

When do we use an Enumerator?

We can use this type instead of defining many constants for fields (such as a status).For example, status can have values active and inactive in different condition. So that, we can use this type as below:

Eg:

So by using it, we can simplify our code as above.

Why are they so special?

Well,

  • It provides enumeration functionality to objects without it.
  • You can control the iteration process in an efficient way using different methods like .each, .select, .next, .peek etc.
  • There is a feature called Lazy enumerator, which will prevent iterate over an infinite collection.
  • It saves a lot of typing(see above example), …
Read More

Rack::Attack – secure you rails app for the real world

Are you worried about the security issues in your Rails app? The rack-attack gem, can help you. Rack::Attack is a rack middleware which provides security to our rails application. It allows us to safelist, blacklist, throttle and to track requests.

  • If the request matches any safelist, it is allowed.
  • If the request matches any blocklist, it is blocked.
  • If the request matches any throttle, a counter is incremented in the Rack::Attack.cache. If any throttle’s limit is exceeded, the request is blocked.
  • Otherwise, all tracks are checked, and the request is allowed.

Implementation

Install the rack-attack gem, or add it to you Gemfile as:

Then tell your app to use the Rack::Attack middleware. For Rails 3+ apps:

Or you can use it in Rackup file as

By default, Rack Attack uses Rails cache. You can override that by setting the Rack::Attack.cache.store value. It is used for throttling. If you want to create use a custom adapter, for example, memory store,  create a file called rack_attack.rb in config/initializers to configure Rack Attack and put the following code in the file:

Throttle

Here we are limiting the request per seconds from the same IP address. Here we are limiting only 3 requests in 10 sec.

Safelist

Above example always allows the request from localhost. And the request is allowed if the value is true.

Blacklist

Here, it blocks the request from ‘2.2.2.2’.

Fail2Ban: Fail2Ban.filter can be used within a blocklist to block all requests from misbehaving clients.

Allow2Ban: Allow2Ban.filter works the same way as the Fail2Ban.filter except that it allows requests from misbehaving clients until such time as they reach maximum retry.

Block logins from a bad user agent

In the above example, if a bad user tries to login, the request is blocked.

Tracks

It tracks request from a special user.

Security issues that Rack Attack addresses

  • Rate limits against DDoS and abusive users

DDoS is short for Distributed Denial of Service. It uses multiple …

Read More

ReactJS for Beginners | A Step by Step Approach

There are many problems while building large applications with data that changes over time. To solve this ,I suggest checking out ReactJS. React lets you express how your app should look at any given point, and can automatically manage all UI updates when your underlying data changes.

React is one of the most popular JavaScript front end libraries which is developed by Facebook. It’s used for handling view layer for web and mobile apps. The main feature of ReactJS is that it allows us to create reusable UI components.  The syntax used in React is JSX which allows you to mix HTML with JavaScript. This is not a requirement – you can still write in plain JavaScript. But this is suggested because this makes writing your components a breeze.

Installation

To install React with Yarn, run:

To install React with npm, run:

The bundlers like webpack or Browserify is recommended. So you can write modular code and bundle it together into small packages to optimize load time.

Use React with Babel to let you use ES6 and JSX in your JavaScript code. ES6 is a set of modern JavaScript features that make development easier.  JSX is an extension to the JavaScript language that works nicely with ReactJS.

React is efficient

ReactJS creates its own virtual DOM where your components actually live. It calculates what changes need to be made in the DOM beforehand and updates the DOM tree accordingly. So it is flexible and gives amazing gains in performance. It can be used on client and server side. This way, React avoids costly DOM operations and makes updates in a very efficient manner.

The smallest ReactJS example looks like this:

It renders a header saying “Hello, World!” on the page. You can see the demo here.

React Features

Read More