Underscores are not allowed as part of domain names

According to rfc1035, underscores (_) are not allowed as part of domain names.

The labels must follow the rules for ARPANET host names. They must start with a letter, end with a letter or digit, and have as interior characters only letters, digits, and hyphen (-). There are also some restrictions on the length. Labels must be 63 characters or less.

This means domain names like my_domain.com or sub_domain.main-domain.com are invalid.

Special thanks to @jclopezdev for finding this out.

JavaScript null vs undefined

In JavaScript null and undefined are rather strange values, both serve a very similar purpose, which is to indicate the absence of a value.

Null

Null is used to assign a reference to an object that you will no longer need or, directly, you want to have the variable declared but initialize it with a value that you still do not know what it will be exactly. In all these cases the best thing to do is to assign a null value.

  var miVariable = null;
  console.log(miVariable);

//log null

undefined

For undefined means that the variable is declared but its value has not yet been defined.

  var miVariable
  console.log(miVariable);

//log null

Both values are values of type false, so if you do a non-strict comparison you will get true undefined, which means that the variable is declared but its value has not yet been defined.

if (null == undefined) {
  return true
 }
//log true

and if you do a strict comparison, because they are not really the same, it returns a false:

if (null === undefined) {
   return true
 }
return false
//log false

Javascript Hoisting

This means that variable and function declarations are physically moved to the beginning of the code and are allocated in memory during the compilation phase.

function welcomeTo(name) {
  console.log("Welcome to " + name);
}

welcomeTo("Magmalabs");
//returns welcome to magmalabs

As you can see hoisting allows you to use a function before declaring it in the code.

welcomeTo("Magmalabs");

function welcomeTo(name) {
  console.log("Welcome to " + name);
}
//returns welcome to magmalabs

And also allows you to use a function after declaring it in the code.

For variables, hoisting only applies to the declaration, not to their assignment. example:

We declare the variable name but we got an undefined

console.log(name); 
var name = magmalabs;
//return undefined

That’s because JavaScript only hoist the declaration

var name;

console.log(name); 
name = magmalabs;
//return undefined

To avoid these errors, it is very important to keep in mind that hoisting only applies to the declaration.

Profiles in docker compose, specify default services

It is common to have multiple services listed in the docker-compose file, sometimes with dependencies, but also, a normal workflow sometimes is to just start everything, like:

docker-compose -f docker-compose.yml -d

And it will start all servies listed with their dependencies, but, what happens if you need to add another service and you do not need it to start along with the rest? The answer is: profiles:

services:
  db:
    image: pg
  cache:
    image: redis
  rails:
    depends_on:
      - db
      - cache
    command: puma
  sidekiq:
    profiles: [ 'jobs' ]
    depends_on:
      - db
      - cache
    command: sidekiq

So, in this case, whenever you do docker-compose up -d it will start only rails with its dependencies: db and cache, it wont start sidekiq by default, but if you really want to start sidekiq, then you need to explicitly type it: docker-compose up sidekiq -d.

Eager load rails associations with nested scopes

It is common to apply some extra scopes when fetching AR relationships, for examples, if we have countries and states, we might want all the countries starting with the letter A and all their states that starts with the letter B, this will automatically create a n+1 query problem since it nees to iterate over each country and fetch all states, but, Rails provides a way to eager load these associations easily:

states_scope = State.where("name ilike 'b%'")
countries = Country.where("name ilike 'a%'")
# This is the magic
ActiveRecord::Associations::Preloader.new.preload(countries, :states, states_scope)

# Now you can invoke coutries.each(:states) and it wont cause queries N+1
countries.map {|country| { country.id => country.states.size }

Normally, you would have to define another relationship in order to eager load the association, but it is not needed using this approach:

class Country < AR::Base
  has_many :states
  has_many :states_starting_with_b, -> { where("name ilike 'b%'") }, foreign_key: :state_id, class_name: "State"
end

# Then
Country.includes(:states_starting_with_b).where("name ilike 'a%'")

But this approach does not scale, it requires to define tons of relationships

Docker compose services with health checks

If you need to add extra checks for services to be up and running before starting another one, you can use healtcheck property:

services:
  pg:
    image: pg/pg-12
    ports:
      - 5432:5432
    healtcheck:
      test: [ "CMD-SHELL", "pg_isready -U postgres" ]
      interval: 5s
      timeout: 5s
      retries: 5
  redis:
    image: redis:5.0.4-alpine
    ports:
      - 6380:6379
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
      interval: 5s
      timeout: 5s
      retries: 5
  app:
    image: railsapp
    depends_on:
      pg:
        condition: service_healthy
      redis:
        condition: service_healthy
    ports: ['3000:3000']
    command: |
      bash -c "bundle exec rails s"

Typeprof Ruby Interpreter in Ruby 3.0+

TypeProf is a Ruby interpreter that abstractly executes Ruby programs at the type level. It executes a given program and observes what types are passed to and returned from methods and what types are assigned to instance variables. All values are, in principle, abstracted to the class to which the object belongs, not the object itself.

Example: 1

 $ typeprof user.rb
# TypeProf 0.12.0

# Classes
class User
  attr_accessor skip_add_role: untyped
  def self.from_omniauth: (?Hash[bot, bot] auth) -> User

  private
  def assign_default_role: -> nil
end

Example 2:

 $ typeprof skill.rb
# TypeProf 0.12.0

# Classes
class Skill
  private
  def acceptable_image: -> nil
end

Example 3:

 $ typeprof ability.rb
# TypeProf 0.12.0

# Classes
class Ability
  attr_accessor user: untyped
  def initialize: (untyped user) -> untyped

  private
  def alias_actions: -> untyped
  def register_extension_abilities: -> untyped
end

Rails + Facebook Oauth Locally with SSL

Recently I had the need to test Oauth with Facebook locally and after creating and configuring the App and everything was working wonderfully ...

until it was not.

Facebook now forces SSL so I had to setup it locally by creating a self signed certificate and running my server with it.

  1. Create your certificate, this script create it as localhost.mumoc.crt and localhost.mumoc.key. Mumoc is my username in my working machine.
name=localhost.$(whoami)
openssl req \
  -new \
  -newkey rsa:2048 \
  -sha256 \
  -days 3650 \
  -nodes \
  -x509 \
  -keyout $name.key \
  -out $name.crt \
  -config <(cat <<-EOF
  [req]
  distinguished_name = req_distinguished_name
  x509_extensions = v3_req
  prompt = no
  [req_distinguished_name]
  CN = $name
  [v3_req]
  keyUsage = nonRepudiation, digitalSignature, keyEncipherment
  extendedKeyUsage = serverAuth
  subjectAltName = @alt_names
  [alt_names]
  DNS.1 = $name
  DNS.2 = *.$name
EOF
)

Make sure to at least add digitalSignature and keyEncipherment to KeyUsage or you won't be able to use it in Chrome

  1. Trust the certificate (I moved it to a config/ssl directory inside my app folder)
mv localhost.mumoc.* config/ssl
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain config/ssl/localhost.mumoc.crt
  1. Run server binding the ssl with the key and certificate
rails s -b 'ssl://localhost:3000?key=config/ssl/localhost.mumoc.key&cert=config/ssl/localhost.mumoc.crt'

You can forward/reverse ports on Android device using adb

I'm developing an Android app as a side project and today I learned about adb forward and adb reverse. Basically, they allow you to forward or reverse traffic to specific ports between an Android device and your development machine.

Let's say I need my app to fetch something from http://localhost:3000/some-data. When the app is running on the phone localhost refers to the phone itself, and my server is running in my dev machine. So, if I do this:

adb reverse tcp:3000 tcp:3000

Now when the app tries to access localhost:3000 it will actually reach out to my dev machine's 3000 port. Very useful if you're developing the app's backend as well (as I am).

Similarly, if I wanted to access a server inside the phone from my dev machine, I could run:

adb forward tcp:5000 tcp:5000

And now if I run curl http://localhost:5000 in my dev machine it will hit the server running on the phone. Pretty neat!

How to run a single test from a file using Cypress

I can run all tests from a file with:

yarn run cypress:run -s path/to/file.spec.js

but what about when I want to run only one test case from that file and not all of them?

We could use only()

// path/to/file.spec.js

it.only('just run this test', () => { ... })

it('not run this test', () => { ... })

// we could also use describe.only() but IDK if that is a bug or a feature xD

Run again yarn run cypress:run -s path/to/file.spec.js to see how the it.only() test will run it

TIL about the attention economy

As a UX designer, the product you create will constantly compete for users’ attention. If users are paying attention to one thing, like a notification on their mobile phone, it means they’re ignoring something else, so users have to be selective about how they spend time! This battle over users’ attention is referred to as the attention economy.

The term attention economy originated with psychologist and Nobel Laureate Herbert A. Simon, who believed that there are limits on what humans can think about and do at one time. Many scientists believe that humans aren’t very good multitaskers; technology should help users, not distract them. The more distracted a person is, the less likely they are to complete a task well.

Set and preserve cookies on and Axios API call

I was using Axios to test an API created in Rails, trying to set up cookies for a User Authentication process. After attempting to get the information back i realize that the cookie was not persistent, due to the lack of one parameter... withCredentials: true So if you want your session to store cookies in the client side and have them available remember to pass it to the call import axios from import axios from 'axios' axios.post(API_SERVER + '/login', { email, password }, { withCredentials: true }) Otherwise the cookie would not be saved.

The Mehrabian rule

Today I learn the Mehrabian 7-38-55 rule. The rule states that: 7% of meaning is communicated through spoken word 38% through tone of voice, and 55 % through body language.

It was developed by psychology professor Albert Mehrabian at the University of California, Los Angeles.

So... it is always a good idea to keep our cameras on at every meeting ;)