Adding a limit to ActiveRecord "last" method

ActiveRecord supports adding a LIMIT to your SELECT statement through the last method:

User.last(10)

results in the following SQL query:

User Load (0.4ms)  SELECT `users`.* 
FROM `users` ORDER BY `users`.`id` DESC LIMIT 10
2019-10-02 by Antonia Horincar

rails: run system tests and normal tests with one command

rails test test:system does only execute unit tests but not the system tests… rails test:system test on the other hand does. Obviously…

see: https://stackoverflow.com/questions/45798635/rails-5-1-run-system-tests-and-normal-tests-with-one-command

2019-09-25 by Philipp Koster

Explicitly mount files with docker-compose

When mounting files in docker compose, like this:

volumes:
  - ./file-to-mount:/target/file-to-mount

an empty directory is created inside the container, if the file-to-mount does not exist! This leads to annoying debug sessions…

One can use the following syntax (with docker-compose 3.4), to mount a file more explicitly:

    volumes:
      - type: bind
        source: ./file-to-mount
        target: /target/file-to-mount

Now, when the file does not exists, it is not possible to start the container.

invalid mount config for type "bind": bind source path does not exist...
2019-09-18 by Philipp Koster

Run command line scripts from within Rake tasks

My usual approach when writing Rake tasks is to import a library and then use its API:

require_relative '../slides'

namspace :slides do
  desc 'Create an empty slideshow'
  task :new do
    Slides.new.write_to_disk
  end
end

Sometimes that is impractical: the API is not public, or you need to invoke a standalone script which only has a command line interface.

I found out Rake implements a ruby method which lets you invoke the ruby program directly:

task :new do
  ruby 'create_slideshow.rb'
  puts 'Created a new slideshow.'
end

There is also a sh method, which allows you to run system commands. Make sure to use the multiple argument version and avoid passing it unfiltered user input.

2019-09-11 by Dimiter Petrov

Install mysql gem on Mac OS X

According to this Gist.

brew install mysql
brew install openssl
gem install mysql2 -v '0.5.2' -- --with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include
2019-09-05 by Andy Pfister

Step through migrations in Rails

tl;dr db:forward is the opposite of db:rollback

bin/rails db:migrate

runs all pending migrations.

If you want to migrate to a specific DB version, you can use

bin/rails db:migrate VERSION=20190730123456

which is rather cumbersome, especially if you only want to run one migration. Therefore you can use

bin/rails db:forward

You can combine it with variable STEP to execute multiple migrations.

bin/rails db:forward STEP=5
2019-08-02 by Mario Schüttel

rubocop-rails

rubocop 0.72.0 removes all Rails cops, since they “[…] want RuboCop to be focused just on Ruby […]” (and I agree with them), see PR #5976.

In order to use the Rails cops after rubocop 0.72.0, we need to add rubocop-rails gem and require it as a dependency in .rubocop.yml:

require:
  - rubocop-rails
2019-07-29 by Mario Schüttel

Enumerable#grep

Ruby enumerables respond to grep. You can use it to quickly filter a collection with a regular expression.

['Marta', 'Mario', 'Bill'].grep(/Ma/)
# => ['Marta', 'Mario']
2019-07-12 by Dimiter Petrov

Update nested maps in Elixir

Being a functional programming language, Elixir is a bit different from other languages when it comes to update a nested data structure.

For example, in javascript we could do:

data = {
  inner: {
    one: {
      a: 1
    },
    two: {
      b: 45
    }
  }
}

data.inner.one.a = 2

In Elixir you have to build a new map with the updated information, for example:

data = %{
  inner: %{
    one: %{
      a: 1
    },
    two: %{
      b: 45
    }
  }
}

new_one = %{data.inner.one | a: 2}
new_inner = %{data.inner | one: new_one}
new_data = %{data | inner: new_inner}

which is not very handy.

In other functional languages like Haskell, there are libraries like Lenses that aims to solve the problem. In Elixir the kernel have an put_in function that acts in a similar way:

data = put_in(data, [:inner, :one, :a], 2)

You can find other similar functions in the Kernel documentation

2019-06-13 by Tiziano Puppi

The query function in Ecto Repo (Elixir)

There is a hidden function in Ecto which is the function query in the Repo module.

This is a wrapper around the Ecto.Adapters.SQL.query and it is injected in the Repo module of your application. It can be called in this way:

MyApp.Repo.query("SELECT * FROM mytable")

This function can also take an array of query parameters like:

MyApp.Repo.query("""                                           
SELECT * FROM mytable
WHERE id = $1
""", [42])

This is quite handy when you need to debug in production, and there is no database client available.

2019-06-07 by Tiziano Puppi

Union, Difference and Intersect with Ruby Arrays

Union

> [:a, :b, :c].union([:b, :c, :d])
 => [:a, :b, :c, :d]

Difference

> [:a, :b, :c].difference([:b, :c, :d])
 => [:a]

Intersect

> [:a, :b, :c] & [:b, :c, :d]
 => [:b, :c]
2019-06-07 by Mario Schüttel

The sample output HTML element

There is an HTML element called <samp> meant for representing computer program output. The specification document has this humorous example:

<p>The computer said <samp>Too much cheese in tray
two</samp> but I didn't know what that meant.</p>