Nicer warning dialogs with Rails and Bootstrap

Ruby on Rails has a very convenient way of presenting a dialog for potentially dangerous tasks that require some confirmation before proceeding. All you have to do is add

data: {confirm: "Are you sure?"}

A problem with those, though, is that most (all?) browsers make the dialogs quite ugly:

Call to Buzz - ugly dialog

For Call to Buzz, I wanted to finally have something better. Thankfully, there’s a very simple solution, as long as you are using Bootstrap: Twitter::Bootstrap::Rails::Confirm. You just add it to your project and the dialog now looks like this:

Call to Buzz - bootstrap dialog

That looks much better, but it’d be nice if it had a nice title, better matching buttons, etc. It’s easy to do by adding some data attributes to the link and the documentation for this gem recommends creating a new method to use instead of link_to when deleting something. I wasn’t very happy with this approach so I resolved it with pure JavaScript so my links remain oblivious to the fact that I’m using this gem:

$(document).ready(function () {
  $("a[data-confirm]").data({
    "confirm-fade": true,
    "confirm-title": "Call to Buzz"
  });
  $("a[data-method=delete]").data({
    "confirm-title": "Warning",
    "confirm-cancel": "Cancel",
    "confirm-cancel-class": "btn-cancel",
    "confirm-proceed": "Delete",
    "confirm-proceed-class": "btn-danger"
  });
});

And with that, the dialog now looks like this:

Call to Buzz - much better bootstrap dialog

Left grouping label with Simple Form and Bootstrap 3

If you are using Simple Form and Bootstrap 3, you probably initialized your app with something similar to:

rails generate simple_form:install --bootstrap

which adds a file called simple_form_bootstrap.rb to your application with many customizations that make Simple Form output nicely formatted Bootstrap 3 forms.

For Call to Buzz, an app I’m building, I had several booleans to display, like this:

Call to Buzz booleans

My problem was that I wanted a label to explain what those booleans are, something like this:

Call to Buzz booleans with label

I achieved that by creating a wrapper that’s a mix between :horizontal_boolean and horizontal_radio_and_checkboxes which I called horizontal_boolean_with_label and looks like this:

config.wrappers :horizontal_boolean_with_label, tag: "div", class: "form-group", error_class: "has-error" do |b|
  b.use :html5
  b.optional :readonly

  b.use :label, class: "col-sm-3 control-label"

  b.wrapper tag: "div", class: "col-sm-9" do |wr|
    wr.wrapper tag: "div", class: "checkbox" do |ba|
      ba.use :label_input
    end

    wr.use :error, wrap_with: {tag: "span", class: "help-block"}
    wr.use :hint, wrap_with: {tag: "p", class: "help-block"}
  end
end
hsbc

Bank says bad debt OK, asset not OK

I want to start buying property with the goal of generating passive income from rent. I’ve read a bunch of books, listen to podcasts, did my research and I stumbled upon a good opportunity that needs more money that I have right now but still a very low amount. So, I need a loan.

I went to a couple of banks to ask for a loan and the answer was essentially: no, we cannot lend you the money to buy this asset that will pay for itself, but if you want to blow it up on a holiday and buy some useless toys, sure, here it is!

Mind you, I can easily pay the loan from my salary. I actually save more money every month than the monthly payment of the loans and I have in the bank a third of the money. My salary has been steadily going up and I’m in an industry in which I’m in a lot of demand. Where my plan is a safe bet, betting on me is even safer.

I’m not one to believe in conspiracy theories but it almost seems like their rules are designed for people to be stupid, instead of smart, with their money; to get in bad debt instead of growing their wealth.

Now, for the nitty gritty details: I asked for a personal loan, some banks disqualify me because you are not allowed to use it for business, some banks disqualify because I’m planning on buying property. They say: “we cannot give you a personal loan for property because you may also get a mortgage”

“Ok, can you give a mortgage then?” “No, because your property is in another country”

“Can you do anything?” “No”

Let’s say I take this supposed mortgage they are so afraid of and the plan fails. Whoever has the mortgage will repossess the property and I’ll pay the bank out of my salary the same way I would if I wanted to spend the money on a caribbean cruise or home improvement.

This feels utterly ridiculous.

Web presence for startups

You build a product, a web or a mobile app and then you need to build a web site to promote it, a.k.a.: the web site. There are several ways of building and maintaining this web site and I have tried most of them and today I have strong opinions about how to do it.

One alternative is to build a custom website as a bunch of HTML and CSS produced by a graphics designer and a coder. Maybe with some server side functionality. If you are building a web app, you might be tempted to mix the web presence with the web app. A lot of tech startups go this route because they have the talent and because it’s the only way to achieve the pristine look that everybody wants and that the industry giants, such as Apple, have.

This is a mistake. The mistake is not considering the process of the evolution of this web site. We only think of the initial task of building it and that tends to be easily achievable, but after that is when the problems really start. Marketing and sales will want constant modifications to that web site both in terms of content and look and feel. They’ll want new landing pages, different kind of analytics. Sometimes they’ll want to scrap the whole thing and start over. This is part of their job and you should just let them do it.

The problem of having the developers of the startup also develop the website is that they need to maintain it and if your marketing/sales people are active enough, they can easily generate enough modifications for a full time person. But your developer needs to be working on the product, not the website. Most changes requested by marketing are going to be relatively small and not as important as improving the product, which means your web presence will be neglected and your marketing person will get annoyed.

The answer is to have CMS and give write access to market and sales. Whether the CMS is WordPress or SquareSpace or something else, it doesn’t matter. I would even recommend to not host it yourself so that the marketing/sales department have a support department that can help them with issues that is not your development team.

This approach will not look as clean, it might feel a bit clunky and people inside and outside the organization are going to constantly fight it. If this is your choice, you’ll have a tough time defending it. I found myself repeating the contents of this blog post to many people over and over again and this is why I’m writing it.

Storing SMTP credentials in secrets.yml in a Ruby on Rails Application

Rails 4.1 introduced the concept of secrets.yml, a file in which you store all the credentials for your app, separated by environment, so for example, development can talk to Test Stripe and production to Live Stripe. Furthermore, this file is capable of picking up environment variables which allows you to divorce credentials from code. Not properly separating credentials from code recently cost Uber the leakage of 50,000 driver names and license numbers.

At Qredo we are very strict about handling credentials, including the ones for SMTP, which in Rails projects are normally stored in config/environments/development.rbconfig/environments/production.rb, etc. Trying to read Rails.application.secrets from those files doesn’t work, because they are loaded before the secrets, so, we came up with this alternative solution.

The environment files that need to use SMTP for delivering email have this common configuration:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
    address: "smtp.example.com",
    port: 587,
    authentication: "plain",
    enable_starttls_auto: true
}

and then, on config/initializers/email.rb we finish configuring our SMTP credentials by reading it from secrets.yml:

if ActionMailer::Base.delivery_method == :smtp
  ActionMailer::Base.smtp_settings[:domain] = Rails.application.secrets.smtp_domain
  ActionMailer::Base.smtp_settings[:user_name] = Rails.application.secrets.smtp_user_name
  ActionMailer::Base.smtp_settings[:password] = Rails.application.secrets.smtp_password
end

In config/secrets.yml you need set those credentials:

development:
  secret_key_base: 123...
  smtp_domain: example.org
  smtp_user_name: postmaster@oderq.com
  smtp_password: <%= ENV["SMTP_PASSWORD"] %>

test:
  secret_key_base: c7f3f62597b14c7287d75c239168fd3a89d3a6cb51beb909679c2609e912aaa3ca0a0aa5df2e191648baed6fe49698527a75dd265d222697576405971f478c98

staging:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  smtp_domain: example.net
  smtp_user_name: staging_user@example.net
  password: <%= ENV["SMTP_PASSWORD"] %>

production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  smtp_domain: example.com
  smtp_user_name: user@example.com
  smtp_password: <%= ENV["SMTP_PASSWORD"] %>

And that’s it! Enjoy bringing SMTP credentials into Rails >4.0 secrets management.

Show a devise log in or sign up forms in another page

This is an update of an old post of similar name but for a newer version of Devise and with better design decisions. The old post was for Devise 1.0.8, this one covers 4.0.0

I was trying to have a single page with both sign in and sign up forms with Devise 4.0.0 but this applies to whenever you want to show log in or registering individually or together anywhere on your site other than the views and controllers Devise creates for you.

For my task, I created a custom controller for it with a single new action as the create actions would be in the respective already existing Devise controllers. Something like this:

class Users::SessionsOrRegistrationsController &lt; ApplicationController
  def new
  end
end

And then I created a new.html.erb (actually, new.html.haml, but I digress) that contained both log in and sign up one after the other. Something like this:

<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
 <%= devise_error_messages! %>

 <div class="field">
 <%= f.label :email %><br />
 <%= f.email_field :email, autofocus: true %>
 </div>

 <div class="field">
 <%= f.label :password %>
 <% if @minimum_password_length %>
 <em>(<%= @minimum_password_length %> characters minimum)</em>
 <% end %><br />
 <%= f.password_field :password, autocomplete: "off" %>
 </div>

 <div class="field">
 <%= f.label :password_confirmation %><br />
 <%= f.password_field :password_confirmation, autocomplete: "off" %>
 </div>

 <div class="actions">
 <%= f.submit "Sign up" %>
 </div>
<% end %>

<hr/>

<h2>Log in</h2>

<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true %>
  </div>

  <div class="field">
    <%= f.label :password %><br />
    <%= f.password_field :password, autocomplete: "off" %>
  </div>

  <% if devise_mapping.rememberable? -%>
    <div class="field">
      <%= f.check_box :remember_me %>
      <%= f.label :remember_me %>
    </div>
  <% end -%>

  <div class="actions">
    <%= f.submit "Log in" %>
  </div>
<% end %>

I actually ended up creating two _form partials and including them. In either case, when you try to render those views, you’ll get errors about some missing methods. You need to provide those as helper methods so my controller actually looks like this:

class Users::SessionsOrRegistrationsController &lt; ApplicationController
  def new
  end

  private

  def resource_name
    :user
  end
  helper_method :resource_name

  def resource
    @resource ||= User.new
  end
  helper_method :resource

  def devise_mapping
    @devise_mapping ||= Devise.mappings[:user]
  end
  helper_method :devise_mapping

  def resource_class
    User
  end
  helper_method :resource_class
end

And now it works.

qredo cropped

I’m Qredo’s new CTO

After more than four years serving as CTO and CEO of the startup I co-founded, it was time for me to move on to new challenges. I wasn’t expecting a challenge as interesting as Qredo to fall on my plate.

Let me start by introducing Qredo. Qredo is an end-to-end-encrypted messaging and storage API. With Qredo you can, in a few lines of code, communicate across apps and devices in a super secure manner. It doesn’t take long watching the news to see how badly the world needs this. We are constantly adding devices and apps to our lives, from smartphones to lighbulbs to thermostats, all connected, all collecting information about ourselves, all sending messages through the internet, many in painfully insecure ways.

Shortly after I started talking with the guys a Qredo, they held a hackathon. Timing couldn’t be better. I loitered around the teams and sat through feedback and presentations. People not experienced at all in building mobile apps had secure messaging mobile apps within a couple of hours. I was expecting a bunch of security nerds and instead I found a very diverse group of people building apps around physical health, mental health, home security, parenting, document co-editing, etc. Apps that have to be secure.

I used to be one of those security nerds when I was a teenager back in the innocent 90s, collecting obscure information, reading books and underground zines. As I grew older I found a fork in my career: specialize in security and be a consultant or specialize in building product. I chose the latter but I never stopped my interest in security. These days I’m the developer that nags you about how insecure your app is, about using PGP, about strong passwords, about properly hashing passwords in your app, etc.

With Qredo, at last, I have the opportunity of doing both things! Working in security and building a new product. Not only that, but a product for developers, an audience I love and I know how to communicate. When I was considering this opportunity I talked to a lot of people and it was unanimous: everybody told me this was the gig for me. I’m not sure if they just knew me well enough or my excitement and enthusiasm was obvious when I described it.

Today is my first day at Qredo, my role will be Chief Technical Officer.