Skip to content

Discriminator is a gem which makes ActiveRecord smart about loading subclasses from the database

License

Notifications You must be signed in to change notification settings

gdpelican/discriminator

Repository files navigation

Discriminator

Discriminator is a gem which makes ActiveRecord smart about loading subclasses from the database. To wit, say we have a class with subclasses:

class Buildings::Base
  def property_value
    raise NotImplementedError.new
  end
end

class Buildings::Library
  def property_value
    "low"
  end
end

class Buildings::Stadium
  def property_value
    "high"
  end
end

class Buildings::SecretBase
  def property_value
    "unknown"
  end
end

We might store these in a table, with a building_type field to determine what type of building it is:

Now, if we try to do something like

Buildings::Library.new(building_type: :library).save
Buildings::Stadium.new(building_type: :stadium).save
Buildings::SecretBase.new(building_type: :secret_base).save
Buildings::Base.all.map(&:class)          # => [Buildings::Base, Buildings::Base, Buildings::Base]
Buildings::Base.all.map(&:property_value) # => NotImplementedError!!

...gross. Ideally, we'd like to load up these records from the databases, with their subclasses already applied! With discriminator, if we add a simple line to our building base:

discriminate Buildings, on: :building_type

Then we get back an ActiveRecord::Relation back, with the appropriate subclass already applied.

Buildings::Base.all.map(&:class)          # => [Buildings::Library, Buildings::Stadium, Buildings::SecretBase]
Buildings::Base.all.map(&:property_value) # => ["low", "high", "unknown"]

This can be exceptionally helpful for a Single Table Inheritance situation, or something like Events where there may be a large number of subclasses which could have very different behaviour per subclass.

I made this gem so I could use it in Loomio.

Installation

(NB that this functionality relies on ActiveRecord >= 4.0.2, when discrimiate_class_for_record was introduced)

Add this line to your application's Gemfile:

gem 'discriminator'

And then execute:

$ bundle

Or install it yourself as:

$ gem install discriminator

Usage

Discriminator defines one method: the discriminate method on ActiveRecord::Base

class Buildings::Base
  discriminate Buildings, on: :building_type
end

Setting a default

By default, discriminator falls back to ModuleName::Base, if a subclass cannot be found but this can be be overridden by the default parameter:

class Kickflips::Basic
  discriminate Kickflips, on: :type, default: :basic
end

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/gdpelican/discriminator. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

About

Discriminator is a gem which makes ActiveRecord smart about loading subclasses from the database

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published