Today I Learned

This project exists to catalogue the sharing & accumulation of knowledge as it happens day-to-day. Posts have a 200-word limit, and posting is open to any Rocketeer as well as selected friends of JetRockets. We hope you enjoy learning along with us.

Handling IP addresses using PostgreSQL

PostgreSQL provides a inet and cidr datatypes for storing net addresses and proceed operations with them.

Host address and it’s subnet can be stored with inet, while cidr can contain only network address:

select inet '';
select cidr ''; -- valid cidr
select cidr ''; -- invalid: cidr must not be a host address
ERROR:  invalid cidr value: ""
LINE 1: select cidr '';
DETAIL:  Value has bits set to right of mask.

In case there’s no number after slash in cidr address the netmask is to equal 32:

select cidr('');

The value above represents a subnet address, while the same value passed to inet represents a host:

select inet('');

Checking inclusion or equality can be performed with >>= and <<= operators:

select inet '' >>= inet ''; -- returns true
select cidr '' >>= inet ''; -- returns false
select cidr '' >>= cidr ''; -- returns true

And getting a netmask by a net address can be performed with netmask:

select netmask(inet('')); -- returns
select netmask(cidr('')); -- returns

JS: Parsing URL

So far, I have used the indexOf operator or regular expressions to get query string values. Today I learned how to make it easier using the URLSearchParams API:

// Assuming "?post=1234&action=edit"

let urlParams = new URLSearchParams(;

console.log(urlParams.has('post')); // true
console.log(urlParams.get('action')); // "edit"
console.log(urlParams.getAll('action')); // ["edit"]
console.log(urlParams.toString()); // "?post=1234&action=edit"
console.log(urlParams.append('active', '1')); // "?post=1234&action=edit&active=1"

Important: Does not work in IE

Typeahead async requests throttling

As everybody else have some legacy code (who does not have it?), and yesterday we faced with problem.

Our internal app have search panel where users could write and get related results. But search was written with typeahead and without any throttling. So it’s triggered full text search on backend side on every input change which leads to DB connection pool exhaustion.

We didn’t found any ready to use solutions, so we added following fix:

    async: true
    source: (query, syncResults, asyncResults) ->
      href = self.href
      # Added getAsyncResults call to throttle requests:
        () ->
            url: href
              query: query
            dataType: 'json'
            (data, textStatus, jqXHR) ->

where getAsyncResults defined before typeahead init:

# throttle is lodash function
getAsyncResults = _.throttle(((fn) ->
  ), 300,
  { ... })

Would be happy if someone find this simple solution helpfull.

Trick: filter falsy values out of an array?

Lets say you need to filter all falsy

0, undefined, null, false, ''(empty string), NaN

values from array.

Of course you can use following construnction:

    .map(item => {
        // ...
    // Get rid of falsy values
    .filter(item => item);

Since the values we don’t want aren’t truthy, the filter above removes those falsy items.

Did you know there’s a clearer way with Boolean?

    .map(item => {
        // ...
    // Get rid of falsy values

Integrate Drawer inside Stack Navigation in React Native

I wanted to use more than one navigation in a React Native app. The documentation didn’t give a clear way to implement this.

Here is what you can do on purpose to add several types of navigation in your React Native app:

import { createStackNavigator, createDrawerNavigator } from 'react-navigation';
import * as Screens from './screens/index';
import Drawer from './components/DrawerMenu';
import getDrawerWidth from './utils/scale';

const AppStackNavigator = createStackNavigator({
  home: {
    screen: Screens.MainScreen,
  about: {
    screen: Screens.AboutScreen,

const AppNavigator = createDrawerNavigator(
    home: {
       screen: AppStackNavigator,
    contentComponent: Drawer,
    drawerWidth: getDrawerWidth,
    headerMode: 'none',

export default AppNavigator;

Create factory with an uploaded file in Rails rspec

To create a factory with an uploaded file in Rails rspec, needs to be included ActionDispatch::TestProcess module in the rails_helper.rb file to use the #fixture_file_upload method in the factories.

# spec/rails_helper.rb
include ActionDispatch::TestProcess

In a factory, when setting the attribute value, use the method #fixture_file_upload, specifying the path and file type.

# spec/factories/import_file.rb
FactoryBot.define do
  factory :import_file, class: ImportFile do
    data { fixture_file_upload 'spec/fixtures/test_file.pdf', 'application/pdf' }

Get most performant function

Let’s say you need to determine which function is execute faster.

Write a function that take array of functions and iterates each of them a certain number of times. Will use the difference in values before and after to get the total time in milliseconds each iteration running.

Play with iterations argument to get more or less reliable results.

const mostPerformantFunction = (fns, iterations = 10000) => {
  const times = => {
    const before =;
    for (let i = 0; i < iterations; i++) fn();
    return - before;
  return times.indexOf(Math.min(...times));
  () => {
    [1, 2, 3, 4, 5, 6, 7, 8, 9, '10'].every(el => typeof el === 'number');
  () => {
    [1, '2', 3, 4, 5, 6, 7, 8, 9, 10].every(el => typeof el === 'number');
]); // 1

How to download files with Axios

A simple example using the Blob() constructor:

export function someFunction(values) {
  return (dispatch) => {
    const method = 'GET';
    const url = 'http://go.api/download_file';
        responseType: 'blob', //important
      .then(({ data }) => {
        const downloadUrl = window.URL.createObjectURL(new Blob([data]));
        const link = document.createElement('a');
        link.href = downloadUrl;
        link.setAttribute('download', ''); //any other extension

How to conditionally render template in Grape resources?

Suppose you need to conditionally render some template in a given endpoint of a Grape resource. There is a env data in Grape::API class that represents Rack environment of the request. env is just a simple Ruby hash and we can pass the template name to it’s api.tilt.template key to render that template:

env['api.tilt.template'] = 'foo/bar.json'

Then let’s define a render method in Base resourсe:

class Base < Grape::API
  def self.inherited(subclass)

    subclass.instance_eval do
      helpers do
        def render(template_name)
          env['api.tilt.template'] = template_name

Now we can use it in the following way:

class ContactsResource < Base
  desc 'Create contact', http_codes: [[201, 'Created']]

  post '/contacts' do
    contact =[:contact])

      render 'v1/contacts/show.json'
      error!({ errors: contact.errors.full_messages }, 422)

Recompose withContext and getContext. Simple example

Very often for nested components you need to transfer some props of the parent. For example size. So, we have the Card component. It contains a Button component.

  // App.js
  <Card size="sm">
    {/* ... */}
      {/* ... */}
      <Button size="sm" onClick={action}>Action</Button>

The size for both components is set by the “size” parameter. In the example above, the parameter passed is indicated for both components. In order not to specify the size for the Button each time, you can use the Context to use the one specified for the Card. If you use recompose, it can be super easy:

  // Card.js
  import { getContext } from 'recompose';
  // ...
  export default withContext(
    { size: PropTypes.oneOf(['sm', 'md', 'lg']) },
    ({ size }) => ({ size }),
  // App.js
  import Button from './Button';
  // ...
  const EnhancedButton = getContext({ size: PropTypes.oneOf(['sm', 'md', 'lg']) })(Button);

Live example

Sort lines in the vim editor

Often when writing code, you need to sort the lines in alphabetical order. For example, in javascript, when importing a large number of modules, it is good practice to organize them alphabetically. Users of the vim editor can do this very simply. It is enough to select in the visual mode all the lines that need to be sorted and enter the command :sort. All rows are sorted!

Custom onChange in React Final Form

Let’s take a case when we need to call our own function to change a state of a specific field in a form (our react final form).

Here is a way to do the exact that: You should pass your function as a parameter and after that just call it inside of the onChange method


const FormGroupAdapter = ({ input, inputOnChange }) => {
    const inputProps = {
        onChange: e => {
            inputOnChange && inputOnChange(e);

    return <input {...inputProps} />;

const handleChange = event => {

const App = () => (
        render={({ handleSubmit, reset, submitting, pristine, values }) => (
            <form onSubmit={handleSubmit}>
                    <label>some label</label>

Live example

How to display numbers with currency formatting in JS?

Use Intl.NumberFormat to enable country / currency sensitive formatting.

const toCurrency = (n, curr, LanguageFormat = undefined) =>
  Intl.NumberFormat(LanguageFormat, { style: 'currency', currency: curr }).format(n);
toCurrency(123456.789, 'EUR'); // €123,456.79  | currency: Euro | currencyLangFormat: Local
toCurrency(123456.789, 'RUB'); // RUB 123,456.79  | currency: Ruble | currencyLangFormat: Local
toCurrency(123456.789, 'RUB', 'Ru-ru') // 123 456,79 ₽  | currency: Ruble | currencyLangFormat: Russian
toCurrency(123456.789, 'USD', 'en-us'); // $123,456.79  | currency: US Dollar | currencyLangFormat: English (United States)
toCurrency(123456.789, 'USD', 'fa'); // ۱۲۳٬۴۵۶٫۷۹ ؜$ | currency: US Dollar | currencyLangFormat: Farsi
toCurrency(322342436423.2435, 'JPY'); // ¥322,342,436,423 | currency: Japanese Yen | currencyLangFormat: Local
toCurrency(322342436423.2435, 'JPY', 'fi'); // 322 342 436 423 ¥ | currency: Japanese Yen | currencyLangFormat: Finnish

Safe Navigation vs Try in Rails (Part 2: Performance)

This Note is an extension of Safe Navigation vs Try in Rails (Part 1: Basic Differences)

Method try() comes from Active Support component of Ruby on Rails. Safe Navigation Operator is Ruby native feature.

Let’s check performance!

require 'benchmark'

class Foo
  attr_accessor :name

foo =
bar = nil do |x|'Successful access: try(...): ')         { 1_000_000.times { foo.try(:name) } }'Successful access: &.: ')               { 1_000_000.times { foo&.name } }'Successful access: control sample: ')   { 1_000_000.times { } }'Failed access: try(...): ')             { 1_000_000.times { bar.try(:nonexistent) } }'Failed access: safe navigation: ')      { 1_000_000.times { bar&.nonexistent } }
                                          user     system      total        real
Successful access: try(...):          0.498216   0.005748   0.503964 (  0.530010)
Successful access: &.:                0.062146   0.000943   0.063089 (  0.069714)
Successful access: control sample:    0.062411   0.001098   0.063509 (  0.069603)
Failed access: try(...):              0.172535   0.004374   0.176909 (  0.194386)
Failed access: safe navigation:       0.054141   0.001029   0.055170 (  0.065502)

Safe navigation is about 7 times faster than method try() for successful navigation and 3 times faster for unsuccessful.

Safe Navigation vs Try in Rails (Part 1: Basic Differences)

There are some ways of preventing errors like undefined method for nil:NilClass.

  • Rails Method try(...)
  • Safe Navigation Operator (&.)
  • Logical operator && (AND)

Here is how these options look like:

user && &&

But there are some differences.

1. If model User hasn’t relation compppany (it may be just a typo or renamed model relation/attribute):

=> nil

You will receive nil and never been know about this typo.

=> NoMethodError: undefined method `compppany' for #<User:0x000000123456789>


user && user.compppany &&
=> NoMethodError: undefined method `compppany' for #<User:0x000000123456789>

Looks better!

2. If model User has relation company, but company is false. false):

=> nil
=> NoMethodError: undefined method `name' for false:FalseClass

Safe Navigation recognized false. Awesome!

user && &&
=> false

Hmmm, it does not look like we want.

3. Performance Read the second part Safe Navigation vs Try in Rails (Part 2: Performance)

Force Downloading of File instead of Opening in Browser

When you go through the link, some files will be opened in the browser. Such behavior is typical for some content types (e.g., images, pdf, etc.)

However, you can force file downloading instead of opening when an user clicks on the link though.

1st way (frontend):

HTML attribute download allows you to do this.

<a href="/public/report.pdf" download="stat_report">

If the value of the attribute is omitted, the original filename would be used. However, be careful. This attribute isn’t supported in some old browsers without HTML5 support. Renaming does not work if the given file stored on another host.

2nd way (backend):

You can set HTTP header Content-disposition.

for Nginx:

location ~* /public/(.+\.pdf)$ {
    add_header Content-disposition "attachment; filename=$1";

for Apache:

<IfModule mod_headers.c>
    <FilesMatch "\.(?i:pdf)$">
        ForceType application/octet-stream
        Header set Content-Disposition "attachment"

How to delete polymorphic models cascade

If you use a polymorphic model in your Rails application, like in example

class Trade < ActiveRecord::Base
  has_many :gl_entries, as: :source, dependent: :destroy

class GlEntry < ActiveRecord::Base
  belongs_to :source, polymorphic: true

You will not be able to add the usual foreign keys for cascading delete records. But this can be implemented using a database.

To do this, you need to write a trigger in the database that will run the delete function for each record.

CREATE FUNCTION deleteGlEntriesOfTrade()
  SET SCHEMA 'public'
  LANGUAGE plpgsql 
  AS $$
    DELETE FROM gl_entries WHERE source_id = AND source_type = 'Trade';
    RETURN OLD;   
CREATE TRIGGER deleteTradesGlEntriesTrigger 

Create a migration and use :)

Sidekiq Stats in Rails

If you use Sidekiq in your Rails project, you can watch tasks statistics through the web interface. Usually, you can find it here: (but in your project path may be different). If you don’t have access there, you can get the same data in Rails console.

To get statistics (number of tasks) by each queue:
=> {"local_cache"=>0, "default"=>0, "ts_delta"=>0, "mailchimp"=>0, "recorder"=>0}

Global statistics are available this way:!
=> {:processed=>61390,

The same stats are available separately:

stats =
stats.processed # number of processed tasks
stats.failed # number of failed tasks
stats.enqueued # number of enqueued tasks

and etc.

Also Sidekiq::Stats allows to look historical data. You can specify period. Something like:

s =, Date.parse('2019-02-05'))
  • first argument: number of days,
  • second argument: date until which return stats (default value is today and can be omitted)
=> {"2019-02-05"=>0, "2019-02-04"=>0}
=> {"2019-02-05"=>0, "2019-02-04"=>0}

Keep clean your git repos!

Many developers don’t keep their local repositories clean. There is a way how to automate it though. Let’s look at a few useful commands:

To clean refs to nonexistent branches in the remote:

$ git fetch --prune

--prune before fetching, remove any remote-tracking references that no longer exist on the remote.

To estimate how many branches merged into dev:

$ git branch --merged dev | wc -l

--merged option can filter list to branches that you have merged into the given branch. Squash and rebase merges usually aren’t detected by --merged.

List of branches merged into dev:

$ git branch --merged dev

List of remote branches merged into dev:

$ git branch --merged dev --remote

If you are courageous then:

$ git branch --merged dev | egrep -v "(^\*|master|dev)" | xargs git branch -d

It removes all local branches that merged into dev (except dev and master). This is a potentially damaging operation. It can delete branches actually needed. So if you use the different approach to work with Git, you could remove some of branches manually instead. I hope you do not store all old branches, do you?

Getting rid of inefficient constantize

Trying to improve performance of one controller I’ve found the following:

def application_klass
  @application_klass ||= "application/#{params[:type]}".classify.constantize

There are Application::Rental and Application::Bridge models in our rails app, so the method above was used in two places:

  1. application_klass.to_s – to get the model name as a string
  2. application_klass.model_name.human – to get a class name without module prefix

I’ve refactored method in the following way:

def application_klass
  @application_klass ||= "application/#{params[:type]}".classify

And it’s occurrences now looks like this:

  1. application_klass – just call this method to get a model name
  2. application_klass.demodulize – using demodulize to split a string with ::

I’ve got rid of unnecessary constantize method, which is quite inefficient: just imagine that your application tries to find a constant in your project with the name specified in the string. See the benchmarks below to evaluate performance gains:

counter = 100_000
type = 'Rental' do |x|'demodulize: ')                   { counter.times { "application/#{type}".classify.demodulize } }'constantize.model_name.human: ') { counter.times { "application/#{type}".classify.constantize.model_name.human } }

                                     user     system      total        real
demodulize:                      3.560000   0.760000   4.320000 (  4.381891)
constantize.model_name.human:    8.500000   0.070000   8.570000 (  8.601007)

Use hash or case-statement in Ruby?

Often, when we need to get a value based on the other one, we’re using a case-statement. Like this

def realizing_trade_type(realizable_trade_type)
  case realizable_trade_type
  when 'buy'
  when 'short'
  when 'buy_contract'
  when 'short_contract'

But, if the conditions and the results are simple values, why don’t we use hash for this? We can :)

  'buy'            => 'sell',
  'short'          => 'cover',
  'buy_contract'   => 'sell_contract',
  'short_contract' => 'cover_contract'

Here is the benchmark of both options, executed 10_000_000 times. It shows that a hash is faster in times for such the kind of usage.

>> require 'benchmark'
>> do |x|'hash') { 10_000_000.times { REALIZING_TRADE_TYPES['buy'] } }'case-statement') { 10_000_000.times { realizing_trade_type 'buy' } }'empty') { 10_000_000.times {} }
                      user     system      total        real
hash              0.990423   0.003412   0.993835 (  1.057612)
case-statement    1.752263   0.004531   1.756794 (  1.762030)
empty             0.380810   0.000728   0.381538 (  0.382153)

So, it’s better to use a hash when you are just retrieving some values (like in the example above). If there is additional logic to execute, a case-statement is still a way to go.

Form_for and Rails attributes API

Attributes API allows you to have complex object with specified structure in fields. But how to make forms with this fields?

The answer is pretty simple: you work with them like with nested attributes.

Let’s say, we have class Provider with attribute address.

class Provider < ApplicationRecord
  attribute :address,, default:

Address has following attributes:

class Provider::Address
  extend Dry::Initializer

  option :country, optional: true
  option :zip, optional: true
  option :city, optional: true
  option :address, optional: true

Form will look like this:

= form_for resource_provider, provider_url do |f|
  = f.fields_for :address do |ff|
      = ff.label 'Country'
      = ff.text_field :country, value:
      = ff.label 'Zip'
      = ff.text_field :zip, value:
      = ff.label 'City'
      = ff.text_field :city, value:
      = ff.label 'Address'
      = ff.text_field :address, value: @provider.billing_address.address

In controller you have to permit parameters:

def provider_params
    params.require(:provider).permit(address: [:city, :zip, :country, :address])

And that’s all. Now, in action method you can assign attributes like this:

resource_provider.attributes = provider_params

Passing events between browser tabs without WebSockets

What if need to pass some event from one browser tab to each others? And we don’t have WebSockets…

It turns out that localStorage raises events 😍

Namely, events are triggered when an item is added, deleted, or changed in another context. In essence, this means that when you change localStorage in one tab, other tabs can find out about this by listening to the storage event of the global window object. For example:

  window.addEventListener('storage', function (event) {
    console.log(event.key, event.newValue);

Of course, there are some restrictions on use (you can read about them here, but for simple cases it is match perfect.

Rename the key name in the javascript object

How to rename the key name in the javascript object? That’s easy!

Lets create function to do that:

const renameKey = (object, key, newKey) => {
  const clonedObj = clone(object);
  const targetKey = clonedObj[key];

  delete clonedObj[key];
  clonedObj[newKey] = targetKey;
  return clonedObj;

Here is clone function:

const clone = (obj) => Object.assign({}, obj);


let contact = { 
    id: 1, 
    name: "contact name"

contact = renameKey(contact, 'id', 'value');
contact = renameKey(contact, 'name', 'label');

console.log(contact); // { value: 1, label: "contact name" };

Use gem Recorder for db log 💪

Gem Recorder tracks changes of your Rails models

For start use this library in Rails 5.2 you need add gem to the Gemfile:

gem 'recorder', github: 'jetrockets/recorder', branch: 'rails_5_2'


> bundle install
> rails g recorder:install
> rails db:migrate

And final step — add to model:

include ::Recorder::Observer
recorder async: false

And it’s all 🎉

For an example - logs can be issued in the representer:

Recorder::Revision.where(item: object).order(id: :DESC).limit(10).map do |revision|
    userId: revision.user_id,
    userEmail: revision.user&.email,
    change: changes_type(revision)

def changes_type(revision)
  if['changes'].include?('drive_file_id') &&['changes'].size > 4 &&['changes']['drive_file_id'].present?
    'Object updated & Document generated'
  elsif['changes'].include?('drive_file_id') &&['changes'].size == 4
    'Document generated'
  elsif['changes'].include?('number') &&['changes']['number'].nil?
    'Object created'
    'Object updated'

But of course this is an abstract example with my data 😏

Command for create zip archive without gem's 📁

class CreateZipCommand
  def call(files)
    # Create temp directory for files 
    tmp_dir = Dir.mktmpdir
    tmp_zip_path = File.join(tmp_dir, "")
    # Move files to the temporary folder you created above do |file|
      download_file(file, tmp_dir)
    # Go to the folder and archive the entire contents
    `cd #{tmp_dir} && zip #{tmp_zip_path} ./*`
    # Return zip path

=> "/var/folders/bk/0c864z710654sx555jpdpx9c0000gn/T/d20190126-7447-d27fpl/")

Most gems for working with archives eat a lot of memory when working with large files. This solution does not have these problems.

Make sure that the zip utility is installed on your computer - it don’t work without it

Reset values in React Final Form w/ keepDirtyOnReinitialize

How to reset values with keepDirtyOnReinitialize in React Final Form after submitting.

The Issue

If keepDirtyOnReinitialize is applied to your form, then form.reset() no longer able to remove field’s value.

The Solution

The Solution is simple— if the form submitted successfully: first change keepDirtyOnReinitialize to false -> perform form reset form.reset() -> and change keepDirtyOnReinitialize back to true.

  render={({ handleSubmit, form }) => (
       onSubmit={(event) => {
       const promise = handleSubmit(event);
       promise && promise.then(() => {
         form.setConfig('keepDirtyOnReinitialize', false);
         form.setConfig('keepDirtyOnReinitialize', true);
      return promise;

How to add index to a large working app on Rails?

Well known fact is that PostgreSQL and many other RDBMS lock write access on the table while the index is being created. It is not acceptable when your project is large enough to allow a downtime for such the small adjustment like a new index. There is a way to avoid the write-lock though. You can create the index concurrently. But how to do it with Rails Migrations? First of all you can pass :algorithm option:

class AddIndexOnBatchIdToFundTrades < ActiveRecord::Migration[5.0]
  def change
    add_index :fund_trades, :batch_id, algorithm: :concurrently

But when you try to run such the migration, you would get the following error:

PG::ActiveSqlTransaction: ERROR:  CREATE INDEX CONCURRENTLY cannot run inside a transaction block
: CREATE  INDEX CONCURRENTLY "index_fund_trades_on_batch_id" ON "fund_trades"  ("batch_id")

That’s because any migration by default is executed inside a transaction. Thankfully there is a way to pass it through - use disable_ddl_transaction! to run your migration without a transaction:

class AddIndexOnBatchIdToFundTrades < ActiveRecord::Migration[5.0]

  def change
    add_index :fund_trades, :batch_id, algorithm: :concurrently

Webhook integration in development with Ngrok 🚀

All begin when I’m using the Pipedrive (is a sales management tool designed to help small sales teams manage intricate or lengthy sales processes) webhook.

The solution was easy I just create an ngrok tunnel

> ngrok http 3000 

Session Status                online
Account                       Andrey (Plan: Free)
Version                       2.2.8
Region                        United States (us)
Web Interface       
Forwarding           -> localhost:3000
Forwarding           -> localhost:3000

and then sent the webhook to the generated address and it works. In local development I can user webhook from another api! It’s work 🚀

To use it you need to do 4 steps:

  1. Register on ngrok
  2. Download ngrok from site
  3. Connect your account
  4. Run it 🚀


In addition, this service has a ngrok-tunel gem that allows you to fully integrate it with your application. But that’s another story 💎

Reset values in React Final Form

How to reset values in React Final Form after submitting

At first I wrote the following code:

  render={({ handleSubmit, form }) => (
      onSubmit={event => {
        handleSubmit(event).then(() => {

If we implement a function like this, we will get an error “Uncaught TypeError: Cannot read property ‘then’ of undefined”, when we try to submit invalid form. Invalid forms — form with validation errors.

The solution

To avoid this error, we need to place handleSubmit(event) to a variable, and if the variable is not undefined call .then().

onSubmit={(event) => {
  const promise = handleSubmit(event);
  promise && promise.then(() => {
  return promise;

Zip two arrays repeating values of the smaller one

So, we have two arrays and we need map each element of the first array to an element from the second. The length of the second array may be less or equal than the first one. What’s if we need to repeat values of the smaller one?

For example, there are two arrays:

const numbers = [1, 2, 3, 4, 5, 6, 7, 8]
const letters = ['a', 'b', 'c']

And we need to get something like:

[ { number: 1, letter: 'a' },
  { number: 2, letter: 'b' },
  { number: 3, letter: 'c' },
  { number: 4, letter: 'a' },
  { number: 5, letter: 'b' },
  { number: 6, letter: 'c' },
  { number: 7, letter: 'a' },
  { number: 8, letter: 'b' } ]

You can use Google or your math skills 😎 and finally will come to this:

const getNormalizedIndex = (index, array) => ((index + array.length) % array.length) % array.length

const numbers_letters =, index) => {
  return {
    number: item,
    letter: letters[getNormalizedIndex(index, letters)]

Run it and you’ll get the expected result.

Render and combine PDF files into one

Render PDF files from HTML templates in Rails can be done using WickedPDF.

First you need to use ActionView to render HTML to a string:

def render_to_string(data)
  action_view =
  action_view.view_paths = ActionController::Base.view_paths

  action_view.class_eval do
    include ApplicationHelper
    include PDFHelper
    # or other helpers

  action_view.render template: 'pdf/template.html',
                     layout: 'layout/pdf.html',
                     locals: { data: data }

Then you can render pdf with the desired settings like this:

# first pdf file with some view settings and values from data1...
pdf1 =
        render_to_string(data1), {
            pdf: 'report1',
            page_size: 'Letter',
            orientation: 'Portrait'
# ...and second pdf file with some view settings and values from data2
pdf2 =
        render_to_string(data2), {
            pdf: 'report2',
            page_size: 'Letter',
            orientation: 'Landscape'

And now you can combine it with CombinePDF gem, that provide you parse method to get PDF content and to_pdfmethod to render the result back to PDF.

combiner =
combiner << CombinePDF.parse(pdf1)
combiner << CombinePDF.parse(pdf2)

Use image files from S3 in WickedPdf

If you need to use image files from S3 in your generated pdf file using WickedPdf, then you need first to download the image. You can create method that does this and add it to the helper.

require 'open-uri'

module PdfHelper
  def embed_remote_image(url, content_type)
    asset = open(url, "r:UTF-8", &:read)
    base64 = Base64.encode64(asset.to_s).gsub(/\s+/, "")

And use image_tag instead of wicked_pdf_image_tag

= image_tag embed_remote_image(file.logo_url, 'image/jpeg')

Manage Elixir versions like RVM & Rbenv

You can install different versions of the Elixir with help of Kiex, like in Ruby with a RVM and Rbenv.

Download and install Kiex

\curl -sSL | bash -s

In .bashrc (or .zshrc if you use z shell), add the following

[[ -s "$HOME/.kiex/scripts/kiex" ]] && source "$HOME/.kiex/scripts/kiex"

Install required Elixir

kiex install 1.7 # or another version

And then you can use any version

kiex use 1.7

How to create zip files on the fly w/o Tempfile

There are many articles about how to archive files from the server and send a zip-file to a client without persisting it on the server. But usually they don’t literally do it, because they use temporary files.

There is a simple way to do it without creating any file though. You just have to put files directly to Zip::OutputStream and then read from it. Btw pay attention: you must rewind the stream before reading it.

# some files objects
def download(files)
  zip_stream = Zip::OutputStream.write_buffer do |zip|
    files.each.with_index(1) do |file, index|
     # file name must be uniq in archive
  # important - rewind the steam
            type: 'application/zip', 
            disposition: 'attachment', 
            filename: ''

How to implement inheritance in Grape resources?

Grape uses specific DSL to define endpoints in API, that’s why you can’t use base class’ instance methods in descendant resources. But there’s one trick:

There’s an #inherited class method in Ruby which is triggered every time some class inherits from ancestor class. It passes one argument - descendant class. Calling descendant’s #instance_eval method we can place any useful stuff inside a block: methods, helpers, before-do’s, etc, in this way evaluating it in context of subclass.

class Base < Grape::API
  def self.inherited(subclass)

    subclass.instance_eval do
      helpers do
        def current_user
          @current_user ||= User.find(params[:user_id])
      # ...

class DocumentsResource < Base
  post '/documents' do
    @document =
    # ...

Note that it’s not real inheritance because Base class has not methods defined inside subclass#instance_eval block.