Torque PostgreSQL – Add support to complex resources of PostgreSQL, like data

types, user-defined types and auxiliary statements (CTE)

This is a plugin that enhance Ruby on Rails enabling easy access to existing PostgreSQL advanced resources, such as data types and queries statements. Its features are design to be as similar as Rails architecture and they work as smooth as possible.

100% plug-and-play, with optional configurations so that can be adapted to your’s project design pattern.

A short rundown of some of the major features:

  • Enum type manager

It creates a separated class to hold each enum set that can be used by multiple models, it also keeps the database consistent. The enum type is known to have better performance against string- and integer-like enums. PostgreSQL Docs

 create_enum :roles, %i(visitor manager admin)

 add_column :users, :role, :roles

 Enum::Roles.admin

 Users.roles

{Learn more}[link:classes/Torque/PostgreSQL/Attributes/Enum.html]
  • Enum set type manager

The enum type is known to have a better performance against string- and integer- like enums. Now with the array option, which behaves like binary assignment, each record can have multiple enum values. PostgreSQL Docs

 create_enum :permissions, %i(read write exec)

 add_column :posts, :creator_permissions, :permissions, array: true

 Enum::PermissionsSet.new(3) # [:read, :write]

 post.creator_permissions.write?

{Learn more}[link:classes/Torque/PostgreSQL/Attributes/EnumSet.html]
  • Period complex queries

This provides extended and complex calculations over date and time ranges. In a few words, you can now store ‘start_time` and `finish_time` in the same column and relies on the methods provided here to fo your magic. PostgreSQL Docs

 add_column :events, :period, :tsrange
 add_column :events, :interval, :interval

 Event.create(title: 'Test', period: ['2019-01-01 12:00:00', '2019-01-01 14:00:00'], interval: 15.minutes)

 Event.overlapping('2019-01-01 13:00:00', '2019-01-01 15:00:00').count

 Event.not_real_overlapping('2019-01-01 11:00:00', '2019-01-01 13:00:00').empty?

{Learn more}[link:classes/Torque/PostgreSQL/Attributes/Builder/Period.html]
  • Has many array association

The idea is simple, one table stores all the ids and the other one says that ‘has many` records on that table because its records ids exist in the column of the array. Like: `Tag has many Videos connected through an array`. PostgreSQL Docs

 add_column :videos, :tag_ids, :bigint, array: true

 Tag.has_many :videos, array: true

 Tag.videos.size

 Tag.videos << another_video

{Learn more}[link:classes/Torque/PostgreSQL/Reflection/AbstractReflection.html]
  • Belongs to many association

The original ‘belongs_to` associations define a `SingularAssociation`, which means that it could be extended with `array: true`. In this case, I decided to create my own `CollectionAssociation` called `belongs_to_many`, which behaves similar to the single one, but storing and returning a list of records.

With this, now you can say things like ‘Project belongs to many employees`, which is more syntactically correct than `Project has many employees` PostgreSQL Docs

 add_column :videos, :tag_ids, :bigint, array: true

 Video.belongs_to_many :tags

 Video.tags.size

 Video.tags << Tag.new(title: 'rails')

{Learn more}[link:classes/Torque/PostgreSQL/Reflection/BelongsToManyReflection.html]
  • Distinct On

MySQL-like group by statement on queries. It keeps only the first row of each set of rows where the given expressions evaluate to equal. PostgreSQL Docs

 User.distinct_on(:name).all

{Learn more}[link:classes/Torque/PostgreSQL/Relation/DistinctOn.html]
  • Auxiliary Statements

Provides a way to write auxiliary statements for use in a larger query. It’s reconfigured on the model, and then can be used during querying process. PostgreSQL Docs

 class User < ActiveRecord::Base
   auxiliary_statement :last_comment do |cte|
     cte.query Comment.distinct_on(:user_id).order(:user_id, id: :desc)
     cte.attributes content: :last_comment_content
   end
 end

 user = User.with(:last_comment).first

{Learn more}[link:classes/Torque/PostgreSQL/AuxiliaryStatement.html]
  • Multiple Schemas

Allows models and modules to have a schema associated with them, so that developers can better organize their tables into schemas and build features in a way that the database can better represent how they are separated.

 create_schema "internal", force: :cascade

 module Internal
   class User < ActiveRecord::Base
     self.schema = 'internal'
   end
 end

 Internal::User.all

{Learn more}[link:classes/Torque/PostgreSQL/Adapter/DatabaseStatements.html]

Download and installation

The latest version of Torque PostgreSQL can be installed with RubyGems:

$ gem install torque-postgresql

Source code can be downloaded direct from the GitHub repository:

License

Torque PostgreSQL is released under the MIT license: