Today I Learned

FactoryBot: Constructing objects using Dry::Types

If you face error similar to the one below

Dry::Struct::Error: [] :some_attribute_name is missing in Hash input

when building objects of the class using Dry::Types and FactoryBot, be advised, that

Although factory_bot is written to work with ActiveRecord out of the box, it can also work with any Ruby class. For maximum compatibility with ActiveRecord, the default initializer builds all instances by calling new on your build class without any arguments. It then calls attribute writer methods to assign all the attribute values. While that works fine for ActiveRecord, it actually doesn’t work for almost any other Ruby class.

The fix is to add following line to your factory definition

initialize_with  { new(attributes) }

Another way to use absolute paths in js 'require'

consider following files structure:

▾ helpers/
▾ services/

in the package.json add:

  "dependencies": {
    "dotenv": "^6.2.0",
    "express": "^4.16.4",
    "helpers": "file:helpers", <-- this line

now in the services/handleSlackCommand.js I can use

const { whatever } = require('helpers/timeHelper');

instead of

const { whatever } = require('../helpers/timeHelper');

Reducing main bundle size with React lazy

On one of our projects we were able to reduce main bundle size from ~1080kB to ~820kB only by lazy loading one library (recharts).

in router file

import React, {Component, lazy, Suspense} from 'react'
//other imports

const StatisticsComponent = lazy(() => import('./path/to/component'))

export class Root extends Component {
      <Router history={history}> 
          // other routes
          <Suspense fallback={<div>Loading...</div>}>
            <Route exact component={StatisticsComponent} path='/statistics' />
      </Router > 

How to make path accessible in Rails Engine

Since routes in engine are isolated by default from main application so that you can have the same routes without clashing using default route helpers like about_path from main app will result in an error when you try to load it from inside the engine or access engine root from main app.

To fix that issue assuming you have an engine mounted:

Blorgh::Engine.routes.draw do
  resources :articles

to enforce using engine roots you need to change about_path to blorgh.about_path and to enforce using main application routes you need to change it to main_app.about_path

ActiveSupport::IncludeWithRange gotcha

Lets see how ruby implements === for ranges.

As documentation say “Returns true if obj is an element of the range, false otherwise”. Let’s try it out.

2.5.1 :001 > (1..10) === 5
 => true

Looks fine… how about if we compare it to another range?

 2.5.1 :001 > (1..10) === (5..15)
 => false

Seems to work properly again. How about if one range is a sub range of the other one.

2.5.1 :004 > (1..10) === (5..6)
 => false

As expected. Those ranges are not equal after all. Or at least (5..6) is not an element that (1..10) holds.

What is surprising, is what happens if we run the same thing in rails console (5.2.0 at the time of writing). Suddenly

[1] pry(main)> (1..10) === (5..6)
=> true

WAT? It now checks if range is included in the original range! Rails do not override === itself though. After looking at what rails adds to range…

[2] pry(main)> (1..10).class.ancestors
=> [ActiveSupport::EachTimeWithZone,

…we have identified this suspicious module ActiveSupport::IncludeWithRange. Its documentation explains everything.

# Extends the default Range#include? to support range comparisons.
#  (1..5).include?(1..5) # => true
#  (1..5).include?(2..3) # => true
#  (1..5).include?(2..6) # => false

Now guess what ruby’s Range#=== uses behind the scenes

              static VALUE
range_eqq(VALUE range, VALUE val)
    return rb_funcall(range, rb_intern("include?"), 1, val);

Yes… include?. The consequences are… there are consequences ;) The most annoying one is related to rspec.

expect(1..10).to match(5..6) # => true
expect([1..10]).to include(5..6) # => true
expect([1..10]).to match_array([5..6]) # => true

It is not possible to easily compare array of ranges matching on exact begin and end values yet disregarding actual order. Also the match behaviour is really misleading in my opinion. The only matcher we can use safely here is eq, as expect(1..10).to eq(5..6) will fail properly.

How to change stubbed return value with another stub?

Simple - just re-define spy as a result of another stub

valid_token = instance_double(ValidToken)
allow(ValidToken).to receive(:new) { valid_token }
allow(valid_token).to receive(:to_s) { '123' }
allow(valid_token).to receive(:clear!) do
   allow(valid_token).to receive(:to_s) { '456' }
valid_token =
valid_token.to_s # 123
valid_token.to_s # 456

Terraform AWS - moving state to another module

If your infrastructure grows and you find that certain resources should be moved to its own module because they need to be shared with others (or you made a mistake by putting them in the wrong module in the first place), you can move the state using CLI rather than recreating resources from scratch.

let’s say you have:

module "s3" {
  source = "./modules/s3"

and inside you defined user with access policy:

resource "aws_iam_user" "portal" {...}

resource "aws_iam_user_policy" "portal" {...}


terraform state mv module.s3.aws_iam_user.portal  module.iam
terraform state mv module.s3.aws_iam_user_policy.portal  module.iam

After that you can move your resource definitions from s3 to iam module. At the end, run terraform plan - terraform shouldn’t detect any changes.

Documentation here.

integer limit is adjustable in activerecord migration

create_table 'example' do |t|
  t.integer :int                 # int (4 bytes, max 2,147,483,647)
  t.integer :int1, :limit => 1   # tinyint (1 byte, -128 to 127)
  t.integer :int2, :limit => 2   # smallint (2 bytes, max 32,767)
  t.integer :int3, :limit => 3   # mediumint (3 bytes, max 8,388,607)
  t.integer :int4, :limit => 4   # int (4 bytes)
  t.integer :int5, :limit => 5   # bigint (8 bytes, max 9,223,372,036,854,775,807)
  t.integer :int8, :limit => 8   # bigint (8 bytes)
  t.integer :int11, :limit => 11 # int (4 bytes)

ReactDatePicker Day off in Summer time issue

If you’re using react-datepicker, and the last time you’ve tested your date-picker was in winter time or sooner, please check if your date-picker still works properly.


  onChange={val => this.setValue(input, val)}
  selected={input.value ? moment(input.value) : null}

Seems pretty basic, right?

Date displayed:

React-date-picker displayed value

Real value:

Real value of date-picker




to props in your react-date-picker.

  onChange={val => this.setValue(input, val)}
  selected={input.value ? moment(input.value) : null}

You can read more about this issue Here.

How to add autoprefixer in webpack

Firstly we need to add this to our project using yarn/npm.

So yarn add autoprefixer.

After a successful installation, we need to declare which browsers we wanna use for our autoprefixer.

To declare that, we need to add to our packages.json file a few lines:

“browserslist”: [
   “> 1%“,
   “last 2 versions”

here, we can set something else (

After that, we need to configure the webpack config file (ie. webpack.config.js).

Firstly we require autoprefixer and we’re setting this as a variable (somewhere on the beginning of the file)

const autoprefixer = require('autoprefixer');


| We need to add postcss-loader loader between css-loader and sass-loader.

use: ['css-loader',
              loader: 'postcss-loader',
              options: {
                plugins: () => [autoprefixer()]

if we have more loaders it could look like that:

  module: {
    rules: [
        test: /\.(sass|scss)$/,
        loader: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader',
              loader: 'postcss-loader',
              options: {
                plugins: () => [autoprefixer()]
        test: /\.css$/,
        loader: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader'],
        test: /\.js/,
        use: ['babel-loader?cacheDirectory'],
        exclude: /node_modules/,

Now, we need to restart the server and you can enjoy working autoprefixer :)

Remove Docker containers/cache

docker system prune -a -f

WARNING! This will remove:
        - all stopped containers
        - all networks not used by at least one container
        - all dangling images
        - all build cache
Deleted Containers:

Total reclaimed space: 14.83GB

SASS / BEM - Not TIL but still some interesting magic

Case 1 - we don’t want to write parent classname again from deep nesting

  $this: &

    margin-top: 2.4rem
    #{$this}__title // so it is .some-class__title
      font-size: 1.7rem


  margin-top: 2.4rem
.some-class.--sub .some-class__title
  font-size: 1.7rem

Case 2 - we want to have a (or any another tag) before parent class from deep nesting

  margin-top: 2.4rem
  @at-root a#{&} // so it is a.btn
    font-size: 1.7rem


  margin-top: 2.4rem
  font-size: 1.7rem

Unicode special characters on IOS Mobile Safari


I’ve created custom checkbox using unicode checkmark: ✔️

Checkbox looks like this: Safari checkbox It looks the same on every browser/device except IOS mobile Safari, where it looks as following: Safari checkbox The problem is that both screens presents unchecked state, but on IOS Safari it looks more like it’s checked.

It turned out, that mobile Safari is the only one which translates ✔️ into emoji, which colors cannot be changed in any way.


To prevent Safari from translating special symbols into emoji add Variation Selector-16:

For HTML like this:


For CSS content like this:

content: '✔\fe0e'  

Where fe0e is mentioned above: Varation-selector-16. This variation code can be found Here

How to get XPath of Capybara's query

Have you ever found yourself in a situation, where you were trying to do something like e.g. click_link 'Approve' and Capybara was not able to find that element on the page despite the fact that it’s quite clearly visible, and you were asking yourself “what the heck is it searching for then?”. Or maybe your find(sth) is failing and you think it’s a bug in the Capybara 😱
Worry no more! Now you can easily check generated XPath used by Capybara*. In most cases, find(*args, **options) translates to:*args, session_options: current_scope.session_options, **options).xpath

E.g. to see XPath for click_on 'Approve':, 'Approve', session_options: current_scope.session_options).xpath

And XPath for find('tbody > tr > td:nth-child(2)'):'tbody > tr > td:nth-child(2)', session_options: current_scope.session_options).xpath

Then you can copy that XPath to the Chrome’s console and test it with $x('xpath').

* Presented solution doesn’t work with some types of more complicated queries, e.g. find('a', text: 'APPROVED') actually uses CSS selector instead of the XPath, and then filter results using Capybara::Result. You can check type of the selector used using .selector.format on your selector query.

Remove sensitive data from git repository.

When you forgot to use secrets from the very beginning - and some secrets landed in your repository eg. login/password/secret_key you can remove them in a simple way using filter-branch for example to remove password you need to use:

git filter-branch --tree-filter "find . -type f -exec sed -i -e 's/password/**REMOVED**/g' {} \;"

It will replace password with **REMOVED** in the whole repo and commits.

Rake / rails console does not work in docker?

When using default ruby image in your Dockerfile (FROM ruby:2.5.1) if you encounter any problems with missing gems in your container when running rake task or rails console:

Could not find rake-x.y.z in any of the sources. Run bundle install to install missing gems.

That’s because you probably used:

RUN bundle install --deployment

You can fix it with:

RUN bundle install --without development test

Making enumerator from method that yields values

Original challenge related to AWS SQS QueuePoller

The challenge was to test a static method that yields multiple values but should stop, when some condition is met.

Let’s imagine such method as follows

class Poller
  def self.poll(condition = -> {})
    counter = 0

    while true do
      yield counter += 1
      break if

The problem is with testing such method. We do not only need to test what it yields, but we also need to test and control when it stops. To control when it stops, we need to access the actual block, but to test what it yields, we either need yield_successive_args matcher or we need to fetch consecutive results.

It is possible by aggregating each yielded value and then asserting them altogether, but the resultant code is not nice. The solution would be to make an Enumerator from the poll method and use next to get consecutive results. It is also easy as described in this blog post. The problem is, that we do not want to write code that is only required by our tests.

So the idea is to add creating enumerators when the block is not provided dynamically to the class when testing.

Poller.define_singleton_method(:poll_with_enum) do |*args, &block| 
    return enum_for(:poll) unless block.present?
    poll_without_enum(*args, &block)
# alias_method_chain is deprecated
# Poller.singleton_class.alias_method_chain(:poll, :enum)
Poller.singleton_class.alias_method :poll_without_enum, :poll
Poller.singleton_class.alias_method :poll, :poll_with_enum

if we turn this into a helper…

def with_enumerated(subject, method_name)
    subject.define_singleton_method("#{method_name}_with_enum") do |*args, &block|
      return enum_for(method_name, *args) unless block.present?
      public_send("#{method_name}_without_enum",*args, &block)

    subject.singleton_class.alias_method "#{method_name}_without_enum", method_name
    subject.singleton_class.alias_method method_name, "#{method_name}_with_enum"

    subject.singleton_class.alias_method method_name, "#{method_name}_without_enum"
    subject.singleton_class.remove_method "#{method_name}_with_enum"

…then we could leverage it in our tests!

with_enumerated(Poller, :poll) do
  $stop = false
  poller = Poller.poll(condition = -> { $stop == true })

  first_value =
  expect(first_value).to eq 1

  $stop = true
  second_value =
  expect(second_value).to eq 2

  expect { }.to raise_exception(StopIteration)

Stubbing responses from AWS services

We have started integration with Amazon SQS recently and did need to write some unit tests related to it. Unfortunately stubbing AWS client library the regular way turned out to be pretty cumbersome and challenging. Fortunately AWS SDK for ruby provides tools that make it pretty comfortable.

# Simple stubbing...
sqs_response_mock =
sqs_response_mock.messages << 'abc')
Aws.config[:sqs] = {
    stub_responses: {
        receive_message: sqs_response_mock

# ...allows properly polling the queue
poller ='')
poller.poll do |msg|
  puts msg.body

# => abc

Documentation can be found here

Handling uniqueness violations in factories

If it happens that your factories’ cross-dependencies result in creating records that violate uniqueness constraint, you can can fix it quick’n’dirty way

FactoryGirl.define do
  factory :day do
    initialize_with {
      Day.where(date: date).first_or_initialize

    sequence(:date) { |n| Date.current + n.days }

Ba aware that this is just a hack, and a hack that would add 1 SQL query to each creation of given object. Preferred way is to fix underlying problem. Still, if you do not care about retrieving the actual instance of object from factory, then different strategy can be used, that would mitigate extra query problem.

FactoryGirl.define do
  factory :day do
    to_create do |day|!
    rescue ActiveRecord::RecordNotUnique

    sequence(:date) { |n| Date.current + n.days }

If for any reason you really need to handle this kind of case, then introducing a custom create strategy (i.e. find_or_create(:day)) might be a way to go.

Mocking database views in Rspec

Sometimes it is a chore to feed database with all data we need for given database view to return results we are after within specs. Fortunately we can utilize temporary tables to mock such database views!

RSpec.configure do |config|
  ActiveRecord::Migration.verbose = false

  config.before(:all, :use_dummy_db_views) do |_example|
    ActiveRecord::Migration.create_table :my_database_view_entries, id: false, force: true do |t|
      t.integer :some_foreign_key      
      t.string :some_name
      t.string :some_code

    MyDatabaseViewModel.table_name = 'my_database_view_entries'

  config.after(:all, :use_dummy_db_views) do |_example|
    MyDatabaseViewModel.table_name = 'orignal_name_of_my_database_view'
    ActiveRecord::Migration.drop_table :my_database_view_entries, force: true    

Then it is just a matter of creating simulated view results, i.e. using factories.

# factory
FactoryBot.define do
  factory :my_database_view_model do
    some_foreign_key 10
    some_name 'Iron Man'
    some_code 'IRON'

# some spec
it 'some expectation', :use_dummy_db_views do
  # ...

Running heavy specs on CircleCI on demand

We have some specs that we do want to run only once a day (smoke specs that connect to actual live services). To handle this case we have introduced following setup:


--exclude-pattern "spec/smoke/*_spec.rb"


- run:
    name: run specs
    command: |
      if [[ ${RUN_ALL_TESTS} == "true" ]]; then
        bundle exec rspec --format progress --exclude-pattern ""
        bundle exec rspec --format progress

This way we can control if some specs are excluded or not, using ENV variable. You can then trigger such build on demand or use CircleCI Workflows.

Downgrading Heroku PG database

Accidentally I’ve provisioned paid plan for PG database. To downgrade such a database you need to:

# safety measures
heroku maintenance:on

# create a new database, new url will be given, for me it was: HEROKU_POSTGRESQL_ORANGE_URL
heroku addons:create heroku-postgresql:hobby-dev 

 # copy current db to ORANGE db

# make new database active

# ... and we are back
heroku maintenance:off

After promotion old database was renamed to PINK then I removed it from heroku panel.

There is also other strategy for downgrade but it does not work for free plan: docs

Passing multiple exceptions to rescue

To rescue multiple classes of exceptions, you have to pass them as a list to rescue method. Passing as an array won’t work, unless you prefix it with * (effectively breaking it into a list)

# Works
  # some code here    
rescue ExceptionA, ExceptionB
  puts "uff, thanks!"

# Doesn't work
  # some code here    
rescue [ExceptionA, ExceptionB]
  puts "uff, thanks!"

# Works
EXCEPTIONS = [ExceptionA, ExceptionB]
  # some code here    
  puts "uff, thanks!"

How to run build on CircleCI recurrently

To run CircleCI build nightly (or at any interval we want), we need a couple of things. First we need to get CircleCI token that will allow us to access CircleCI API.

Next we need a script, that will trigger the build. In example below we also provide an extra build parameter RUN_ALL_TESTS that effectively allows us to conditionally run some specs we do not want to run during regular build.

namespace :ci do
  desc 'Runs build on CircleCI'
  task build: :environment do
    command = 'curl -X POST --header "Content-Type: application/json" ' \
      "--data '{\"build_parameters\": {\"RUN_ALL_TESTS\": \"true\"}}' " \
      '' \


Last thing is to schedule the build. Simplest way is to use Heroku Scheduler and just configure it to run rake ci:build command.

Edit: No longer valid! For Circle 2.0 we can use workflows for the same effect!

Making factory_bot work with read-only models

In one of our apps we need to ensure that all models are in read-only mode. Still, for testing purposes we need to be able to create instances of such models. Following code makes it possible.

# spec/models/application_record_spec.rb
require 'rails_helper'

RSpec.describe ApplicationRecord do
  it 'ensures all descendants are read-only' do
    Unit =

    expect( eq true
    expect { Unit.create! }.to raise_exception(ActiveRecord::ReadOnlyRecord)

  it 'allows creating objects using factories' do
    Unit =

    expect { read_only(:unit) }.to change { Unit.count }.by(1)
  it 'disallows updating objects' do
    Unit =
    unit = read_only(:unit)

    expect { unit.update_attributes!(name: 'New name') }.to \

# spec/support/factory_bot.rb
module FactoryBot
  module Strategy
    class ReadOnly <  Create
      def result(evaluation)
        is_readonly = evaluation.object.readonly?
        evaluation.object.define_singleton_method(:readonly?, -> { false })

        super.tap do |object|
          object.define_singleton_method(:readonly?, -> { is_readonly })

FactoryBot.register_strategy(:read_only, FactoryBot::Strategy::ReadOnly)

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods

# spec/factories/units_factory.rb
FactoryBot.define do
  factory :unit do
    sequence(:name) { |i| "Unit #{i}" }

Configuring capybara-screenshot with Heroku

Due to many problems with our capybara-based automations we execute in Sidekiq on Heroku, we did need some visual feedback of what is going wrong. Unfortunately due to read-only nature of Heroku’s file system we did need to customize capybara-screenshot a bit to achieve this functionality.

# initializers/capybara_screenshot.rb

Capybara::Screenshot.s3_configuration = {
  s3_client_credentials: {
    access_key_id: ENV['DEBUG_BUCKET_S3_KEY'],
    secret_access_key: ENV['DEBUG_BUCKET_S3_SECRET'],
  bucket_name: ENV['DEBUG_BUCKET_S3_BUCKET']

# Default available methods use lunchy gem. 
# We do neither need nor want that. 
# Hence introducing simplified version.
Capybara::Screenshot.class_eval do
  def self.save_screenshot
    new_saver(Capybara,, false).save

Capybara.save_path = '/tmp' # Writeable directory on heroku

Then, we have decided to rescue and re-raise all exceptions, but also save a screenshot in the process…

rescue => exception # rubocop:disable Style/RescueStandardError
  raise exception


We’ve recently experienced some peculiar errors when processing capybara-based automation scripts on Heroku. Most of the time, the error returned did not show anything useful…

Selenium::WebDriver::Error::NoSuchDriverError: no such session

yet for a brief period of time, following error was reported when attempting to access capybara session

Selenium::WebDriver::Error::UnknownError: unknown error: session deleted because of page crash
from tab crashed

Finally, after spotting this comment we’ve reduced chrome window size from 1920,1200 to 1440,900 and the problem is no longer present.

The root reason is unknown, but most likely it is at least partially related to running out of memory (reference). Most of recommendations when using docker in this scenario, was to increase shm-size, by providing --shm-size=2g to docker run. That was not an option for us though…

Hope it helps in case you run into similar situation.

Fetching single file from private repository (+ CI)

We had a situation in which we did need to write an API for an app, but decided to keep it in separate repository and deploy as separate app. This API would use original app’s database in read-only mode. The problem was how to prepare database structure for testing purpose. We’ve decided to use structure.sql from original app, but we did want to keep it in sync somehow.

First thing was to get Github’s personal access token

Then, locally we’ve just altered bin/setup to include following code

require 'dotenv/load'
puts "\n== Importing database structure =="
  system! %{curl -H 'Authorization: token #{ENV.fetch('DEVELOPER_ACCESS_TOKEN')}' -H 'Accept: application/vnd.github.v3.raw' -O -L}
  system! 'mv structure.sql db/structure.sql'

  puts "\n== Preparing database =="
  system! 'RAILS_ENV=test bin/rails db:drop db:create db:structure:load'

while for CircleCi we did need to add following entry to .circleci/config.yml

      - run:
          name: setup-db
          command: |
            curl \
              --header "Authorization: token ${DEVELOPER_ACCESS_TOKEN}" \
              --header "Accept: application/vnd.github.v3.raw" \
              --remote-name \
            mv structure.sql db/structure.sql
            bundle exec rake db:create db:structure:load --trace

Obviously do not forget to ensure correct value for DEVELOPER_ACCESS_TOKEN in your .env and on CircleCI.

Two ways of initiating team building during a meetup

The first way of encouraging people to get to know each other during a meetup is to begin the event with the networking part. You can start a discussion about the topics of the presentations from the agenda. By asking the crowd about their suggestions about the aforementioned matter you give people some space to articulate their thoughts and share opinions with one another.

In my opinion, this approach may not always work so well. Why? Because a lot of people will not engage in a conversation as for some of them expressing their thoughts in front of people they do not know so well could be stressful. They might also feel like they do not know the topic well enough to give any constructive comments or they are simply not interested in a given subject. We also should take into consideration that some people are simply shy and do not like to be the center of attention. In the end, people form groups by themselves, always made up of those who are more or less acquainted with, that is why the problem of pushing people out of their comfort zones to mingle appears.

So how to help them in talking to one another and connect more people during the meetup? Let’s take a closer look at the second way of initiating team building during an event like this.

You can create groups at random, which gives you a higher chance of having small groups of people who have never met before. The participants will find interesting topics to discuss by themselves, especially if you help them a bit by printing out and distributing some typical IT topic ideas. Never strictly dictate the topic, though. They should feel like in a normal, friendly meeting. From my experience, this is a much better solution. This way of organizing meetups gives people more opportunities to talk. We can find a subject which we are interested in. So for shy, not confident people, we are lowering the bar for joining the conversation, speaking up and sharing their opinions.

Summary/comment: To sum everything up, I had the opportunity to participate in both of the above-mentioned types of meetings (these were meetings of the Ruby Users Group) and in my humble opinion, the latter was in many ways superior when it came to making people talk to each other and enabling them to get to know each other better.

Simplifying Circle CI setup for Crystal

Rather than setting up test environment for Crystal by yourself you can use official docker image:

version: 2
      - image: crystallang/crystal:0.25.0
      - checkout

      - restore_cache:
            - shards-{{ checksum "shard.lock" }}
      - run:
          name: Install shards
          command: |
            shards check || shards
      - save_cache:
          key: shards-{{ checksum "shard.lock" }}
            - lib/
            - .shards/

      - run:
          name: Run specs
          command: crystal spec