postgres_ext: Adding Postgres data types to Rails

By: Dan McClain

Over the past few weeks, I have been working on a new gem which adds support to Rail’s ActiveRecord for PostgreSQL’s native data types. I am happy to announce that I have released the postgres_ext) gem.

postgres_ext supports for ActiveRecord version 3.2 and above (at this time). Parallel to my development, I plan to submit pull request to Rails master, so that postgres_ext will not be needed in Rails 4.0.


Migration/Schema support

postgres_ext adds migration and schema.rb support for the following PostgresSQL type:

  • INET
  • CIDR
  • UUID
  • Arrays

You can create columns with the following migration methods:

create_table :examples do |t|
  t.inet :ip_address
  # INET Column

  t.cidr :subnet
  # CIDR Column

  t.macaddr :mac_address
  # MACADDR Column

  t.uuid :unique_id
  # UUID Column

  t.integer :int_array, :array => true
  # Integer[] Column

These migrations will be captured in your schema.rb file, so you don’t have to use the structure.sql file if these types are your only reason. In fact, if you are using these only supported types with structure.sql, including the postgres_ext gem should allow you to correctly rake db:schema:dump your database.

Migration/Schema.rb support documentation

Type Casting

postgres_ext converts INET and CIDR values to IPAddr instances, and coverts arrays to array objects of the column type (integer arrays are cast as an array of integers, INET arrays to are cast to an array of IPAddrs).

INET Type Casting example

create_table :inet_examples do |t|
  t.inet :ip_address

class InetExample < ActiveRecord::Base

inetExample =
inetExample.ip_address = ''
# => #<IPAddr: IPv4:>

inet_2 = InetExample.first
# => #<IPAddr: IPv4:>

Array Type Casting example

create_table :people do |t|
  t.integer :favorite_numbers, :array => true

class Person < ActiveRecord::Base

person =
person.favorite_numbers = [1,2,3]
# => [1,2,3]

person_2 = Person.first
# => [1,2,3]
# => Fixnum

Type casting documentation

Another gem born out of necessity

I have also released pg_array_parserr), a C extension which parses PostgreSQL array values and returns an array of strings. This gem is used by postgres_ext to retrieve the array values before casting them to the required type.

Plans for postgres_ext

INET, CIDR and MACADDR support has already been added to Rails 4. My next step is to submit a pull request to add UUID migration support and Array support to Rails master. Then I plan to backport Rails 4’s hstore support back to postgres_ext. After adding support for the other PostgreSQL types, I plan to add support to arel for PostgreSQL type specific where clauses (ie ANY for array comparison, << and >> for INET and CIDR comparisons.