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.
Features
Migration/Schema support
postgres_ext adds migration and schema.rb
support for the following
PostgresSQL type:
- INET
- CIDR
- MACADDR
- 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
end
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
end
class InetExample < ActiveRecord::Base
end
inetExample = InetExample.new
inetExample.ip_address = '127.0.0.0/24'
inetExample.ip_address
# => #<IPAddr: IPv4:127.0.0.0/255.255.255.0>
inetExample.save
inet_2 = InetExample.first
inet_2.ip_address
# => #<IPAddr: IPv4:127.0.0.0/255.255.255.0>
Array Type Casting example
create_table :people do |t|
t.integer :favorite_numbers, :array => true
end
class Person < ActiveRecord::Base
end
person = Person.new
person.favorite_numbers = [1,2,3]
person.favorite_numbers
# => [1,2,3]
person.save
person_2 = Person.first
person_2.favoite_numbers
# => [1,2,3]
person_2.favoite_numbers.first.class
# => Fixnum
Another gem born out of necessity
I have also released pg_array_parser, 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.
DockYard is a digital product agency offering exceptional user experience, design, full stack engineering, web app development, custom software, Ember, Elixir, and Phoenix services, consulting, and training.