Ecto: How to build dynamic fragments and case statements

I needed a way to create a dynamic case statement for an order_by/3 call in a Phoenix app using Ecto.

Take the following example:

order_by_lowest_amount(queryable, rates) do
  order_by(queryable, [x], fragment(
    """
    CASE
      WHEN ? = 'USD' THEN ? * ?
      WHEN ? = 'AUD' THEN ? * ?
      # ...
    END ASC
    """,
    x.currency, x.amount, ^Map.get(rates, :USD, 1),
    x.currency, x.amount, ^Map.get(rates, :AUD, 1),
    # ...)
end

Javascript: Prevent blocking during load of inline background images

We’re using Turbolinks to speed up page loads, but this is an issue we’ve found that goes all the way down to the DOMContentLoaded event. In all our projects we always had an assumption that images would not block the page:load or DOMContentLoaded event. We mainly use these events to know when the DOM is ready for selecting elements.

Elixir: Super easy way to create random alphanumeric ids

With Nomad Rental we had a simple task; we want to create a random alphanumeric ID of six characters (e.g. QJ21KK). Elixir is a wonderful language that makes this incredibly easy to understand in code form:

def gen_reference() do
  min = String.to_integer("100000", 36)
  max = String.to_integer("ZZZZZZ", 36)

  max
  |> Kernel.-(min)
  |> :rand.uniform()
  |> Kernel.+(min)
  |> Integer.to_string(36)
end

We define the lower and upper bounds in alphanumeric, convert them to integers and find a random number in between them. We then turn the random integer back to alphanumeric and voila!

Phoenix: Automated build and deploy made simple

I’ll detail how we’ve made a straightforward build and deploy process for our Phoenix setup at Nomad Rental. I found some blog posts that led us most of the way but thought it would be great to have an A-Z guide, that can be easily modified for your particular setup.

This blog post by Piotr Włodarek helped us a long way.

Phoenix: How to easily preview e-mails in a Bamboo setup

I’ll show how you can easily add a simple controller to preview your e-mails. Bamboo has a sent_email plug to view all emails as they are sent, but if you use HTML layout, or if you’ve an intricate e-mail process it would be much easier to just preview them instead. Fortunately it’s super easy to build a controller to preview your HTML (or plain text) e-mails.

Phoenix: Build a full-fledged API in five minutes

I’ll show how you can build a full-fledged API in minutes. It’s super fast to prototype in Elixir, but it can take some time to figure out all the working parts. Lucky for us, we can use some hex libraries that’ll do most of the work for us.

Electron: How to build, package and sign 3rd-party binaries with Electron-Builder

Working on Blazing Bookkeeper, an ORC based document scanner, I had to build and package various libraries and binaries through electron-builder. I couldn’t find any guides detailing this, so I’ll outline the process we took to make it work.

Rails 4: Add data-error attribute to form field instead of using wrapper

I wanted to have data-error on the form field instead of the standard rails error wrapper <div class="field_with_errors"></div>. With a data attribute we can do some much nicer handling of the form field.

Non-obtrusive multi-language redirection (with RoR example)

At Spaces we’ve implemented a non-obtrusive redirection for our multi-language, multi-domain websites. Too many websites have the awful habit of forcing content to visitors that the visitor didn’t request in the first place.

How and why we implement Intercom to only load when required (maintaining the privacy of our users)

At Spaces we’ve been looking into various ways of offering support. Intercom seemed to be a great solution, but we were surprised to see the lack of privacy, in that they record personal information for anyone who simply signs in by default.

The Intercom rails gem collected user id, email, name, and signup date by default. We contacted them about how we could increase the privacy, and the response was in short that we had to use their API, with a far worse UX, if we even could get that to work in the first place.