Creating a Rails Concern which accepts arguments

I wanted to create a Rails Concern which can accept arguments from the parent and/or it’s inherited sub-classes.

Most examples I came across online were simple Concerns which didn’t take any parameters or arguments. So here’s how I went about creating one. Let’s call it Arguable for the sake of this blog post.

Implementation:

module Arguable
  extend ActiveSupport::Concern

  module ClassMethods
    attr_reader :arguable_opts

    private

    def arguable(opts={})
      @arguable_opts = opts
    end
  end

  def do_something
    opts = get_arguable_opts
    excluded_attrs = opts[:except] || []
    included_attrs = opts[:only] || []
    custom_attrs = opts[:custom] || {}
    #Do something with the attrs here
    puts opts
  end

  def get_arguable_opts
    if self.class.arguable_opts.blank? && self.class.superclass.arguable_opts.present?
      opts = self.class.superclass.arguable_opts
    elsif self.class.arguable_opts.present? && self.class.superclass.arguable_opts.present?
      opts = self.class.superclass.arguable_opts.merge(self.class.arguable_opts)
    else
      opts = self.class.arguable_opts
    end
    opts || {}
  end
end

Usage:

class Shape > ActiveRecord::Base
  include Arguable
  arguable exclude: [:id]
end

class Circle > Shape
  include Arguable
  arguable include: [:order], custom: {foo: 'bar'}
end

Circle’s options would then have exclude available from it’s parent class and all the other include and custom options available from the subclass.

> c = Circle.find(1)
> c.do_something # => {exclude: [:id], include: [:order], custom: {foo: 'bar'}}

How to install FFmpeg on Ubuntu

I had to dig around to find these simple instructions on how to install FFmpeg on Ubuntu. So I decided to write them down for future reference.

1) First, add Jon Severinsson’s official FFmpeg ppa to your sources. More details here:

sudo add-apt-repository ppa:jon-severinsson/ffmpeg

2) Get the latest list of available software from all the sources (including the newly added ppa):

sudo apt-get update

3) Now go ahead and install:

sudo apt-get install ffmpeg

That’s it. You should be all set!

Fixing PostgreSQL locale issues on Ubuntu/Debian

PGError: ERROR: encoding UTF8 does not match locale en_US
DETAIL: The chosen LC_CTYPE setting requires encoding LATIN1.

You are here probably because you encountered an error like the one above. After a bit of searching I found and tried various different methods from random articles and gists. Although none worked for me as well as what I’m about to document. Which is why I’m blogging about this for future reference.

Although before we proceed, a word of caution - Backup your database. This has NOT been tried in production so use at your own risk!

1) Update the default locale on your system

Note: These commands are specific to Debian/Ubuntu.
Source: https://blog.lnx.cx/2009/08/13/fixing-my-missing-locales/

$ locale-gen en_US.UTF-8
$ update-locale LANG=en_US.UTF-8

2) Now let’s recreatetemplate1</source> based on the new locale

First we’ll need to switch to the database user. Typically that’ll be “postgres”

$ sudo su postgres
$ psql

OR

$ psql -U postgres

Next issue the following set of commands in order:

UPDATE pg_database SET datallowconn = TRUE WHERE datname = 'template0';
\c template0
UPDATE pg_database SET datistemplate = FALSE WHERE datname = 'template1';
DROP DATABASE template1;
CREATE DATABASE template1 ENCODING = 'utf8' TEMPLATE = template0 LC_CTYPE = 'en_US.utf8' LC_COLLATE = 'en_US.utf8';
UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template1';
\c template1
UPDATE pg_database SET datallowconn = FALSE WHERE datname = 'template0';
\q

If you didn’t see any errors, you should now be all set. You can now go ahead and log out of the postgres user account:

$ exit

URL Validation with KnockoutJS

I recently found myself having to implement URL validation in KnockoutJS. Here’s how I went about doing that:

1) Add Knockout-Validation plugin to your project.

2) Create a custom rule to validate URLs based on the RegEx by Diego Perini found here:

ko.validation.rules['url'] = {
  validator: function(val, required) {
    if (!val) {
      return !required
    }
    val = val.replace(/^\s+|\s+$/, ''); //Strip whitespace
    //Regex by Diego Perini from: http://mathiasbynens.be/demo/url-regex
    return val.match(/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.‌​\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[‌​6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1‌​,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00‌​a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u‌​00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/i);
  },
  message: 'This field has to be a valid URL'
};
ko.validation.registerExtenders();

3) You are all set. You can now use it either one of these ways:

JS:

jsvar someURL = ko.observable().extend({ url: true });

HTML:

html<input type="text" data-bind="value: someURL.extend({ url: true })" />

Ensuring reliable email delivery with DNS records

If your web app is sending emails, you will need to have these three DNS records configured properly to ensure reliable email delivery and avoid ending up in spam/junk folders:

PTR - It’s a pointer to a canonical name. Unlike a CNAME, DNS processing does NOT proceed but it just resolves an IP address to a fully-qualified domain name (FQDN). So just the name is returned. It’s also known as a Reverse DNS Record.

The most common use is for implementing reverse DNS lookups to check if the server name is actually associated with the IP address from where the connection was initiated. Here’s what it would look like:

SPF - Sender Policy Framework (SPF) is an email validation system designed to prevent email spam by detecting email spoofing, a common vulnerability, by verifying sender IP addresses.

Microsoft has a great 4 step wizard to guide you through creating a SPF record.

If you have a Google Apps domain and you are using a 3rd party email delivery service such as SendGrid, here’s what it would typically look like:

"v=spf1 a mx include:_spf.google.com include:sendgrid.net ~all"

without Google Apps:

"v=spf1 a mx include:sendgrid.net ~all"

DKIM - DomainKeys Identified Mail (DKIM) is a method for associating a domain name with an email message, thereby allowing a person, role, or organization to claim some responsibility for the message. The association is set up by means of a digital signature which can be validated by recipients.

This is usually set by the email delivery service you are using. Checkout their account settings to make sure its turned on.

Here’s some more useful links:

How can I check if my DKIM and SPF records are valid? by Postmark
What are SPF and DKIM and do I need to set them up? by Mandrill
How do I add DNS records for my sending domains? by Mandrill
Email Deliverability Guide by SendGrid