Skip to main content
  1. Posts/

ActiveRecord Except

·375 words·2 mins·
Ruby on Rails Software Development
Table of Contents

August 19 was Whyday, and to commemorate it, I decided to write a gem called activerecord-except.

What is it?
#

activerecord-except is a Ruby gem that extends the functionality of ActiveRecord, allowing you to select all the fields from a table, except the ones that you specify. For example, if you have a table users.

development_db=# \d users
      Table "public.users"
            Column             | 
-------------------------------+-
 id                            | 
 username                      | 
 password                      | 
 email                         | 
 first_name                    | 
 last_name                     | 
 phone                         | 
 ...
 created_at                    | 
 updated_at                    | 

And you want to get all the fields except for the password, you’d have to pass each of them in your select clause like so

User.all.select(:id,
                :username,
                :email,
                :first_name,
                :last_name,
                :phone,
                ...
                :created_at,
                :updated_at)

Instead, using activerecord-except, can simplify your statement by saying only the field you don’t want, in this case, the password one

User.all.except(:password)

How does it work?
#

Under the hood, the except clause makes use of the traditional select clause. So our previous example will produce the following query

SELECT "users"."id",
       "users"."username",
       "users"."first_name",
       "users"."last_name",
       "users"."phone",
       "users"."created_at",
       ...
       "users"."updated_at"
  FROM "users"

This is because the SQL language doesn’t provide such functionality out of the box.

I don’t know what is the reason for this. I can only speculate that it’s to be more explicit and not be caught by surprise if a field in a table gets added/deleted/changed. However, * is also wildly used. In Rails for example, it is what you get, when you don’t specify a select clause in your query.

The way I managed to make it work is by adding a method to ActiveRecord::Relation which asks the model for all its attributes and rejecting those that match with the ones passed as arguments.

klass._default_attributes
     .keys.map(&:to_sym)
     .reject { |attr| fields.include?(attr) }
As you can see, I’m using _default_attributes which starts with an underscore. This can mean that the method is not intended to be relied upon.

Whether or not you might want to use in production, I leave up to you, where I really see the benefit of activerecord-except is for writing one-off scripts to extract data, because it makes them much easier to read.

Want to give it a try?
#

You can install it from rubygems or you can check the source code on GitHub.

Reply by Email

Related

JSON Data Type
·450 words·3 mins
Software Development Application Development Data Modeling PostgreSQL Ruby on Rails
Running a Patched Ruby on Heroku
·660 words·4 mins
Platforms Ruby on Rails Software Development
The Maintenance Price Tag
·424 words·2 mins
Software Development Technical Debt Product Management Team Culture Business Value
10 Years Working Abroad
·985 words·5 mins
Software Development Reflections
Rails Routing: Advanced Constraints for User Authentication without Devise
·431 words·3 mins
Ruby on Rails Authentication Routing Testing Application Development
Using a Hackathon to Stress Test Your Development Process
·666 words·4 mins
Software Development Team Culture Reflections