Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Ruby ORMs

Ruby ORMs

Abstract

Rails is really a collection of pieces that can be put together to create a web app. You can enhance or replace many of the components - how you write views, how controllers work, and how you build models. While models are built on top of ActiveRecord in the default Rails stack, you've got a lot of other choices.

In this presentation, we'll take a look at ActiveRecord and alternative ORMs. We'll discuss the pros and cons of each, and take a look at what the future will bring us.

ORMs

  • ActiveRecord
  • DataMapper
  • Sequel
  • ROM
  • Perpetuity
  • Mongoid
  • MongoMapper
  • Mince

ActiveRecord Pros

ActiveRecord is the 800-pount gorilla.

  • Ubiquitous
    • Everyone knows it
    • Lots of people improving on it
    • Plugins usually assume you're using it
    • Plenty of documentation
  • Well-tested
  • Well-understood
  • Super easy to get started
    • It's included in Rails by default
  • ARel behind the scenes

ActiveRecord Cons

  • Class inheritance
    • Not (current) idiomatic Ruby
    • Prevents a hierarchical class structure
      • TODO: Show an example where this would be useful
  • Persistence and behavior in one class
    • Violates SRP
    • Makes testing harder and slower
      • TODO: Show examples of slow tests and fast test
  • Validations are also included (another responsibility)
  • No Identity Map
    • TODO: Show example of where this is a problem
  • Have to look 2 places to find everything:
    • Attributes (fields) are declared in the schema
    • Relations are declared in the model itself

ActiveRecord Add-Ons

  • Includable ActiveRecord
    • Solves the inheritance issue
  • Annotated Models (TODO: or its replacement)
    • Kind of solves the problem of fields and relations in different places
  • Virtus::ActiveRecord or mini_record
    • Solves the problem of fields and relations in different places
  • Squeel
    • Gives a more Ruby-like API for scopes
  • Attachments (Paperclip, etc.)
  • Authentication (Devise, etc.)

DataMapper

  • Actually uses the Active Record pattern
  • Supports a lot more than just SQL on the back end
  • No further development (last updated 2012-08-27)

Sequel

  • Probably the best alternative right now

  • Good documentation

  • Leverages database features (like foreign key constraints)

  • Supports almost any SQL database you can think of

  • Thread safety, connection pooling

  • Awesome feature - set a model to a subset of a table:

DB = Sequel.connect('sqlite://blog.db')
class Post < Sequel::Model
  set_primary_key [:category, :title]
  set_dataset DB[:my_posts].where(category: 'ruby').select(:category, :title, :content).order(:date)
end

ROM

  • Should be the best alternative in the future
  • Previously was called DataMapper 2
    • But has diverged a lot since the name change
  • Truly implements the Data Mapper pattern
  • Taking longer to get to 1.0 than hoped
    • Developers seem to be low-level / bottom-up types
  • Supports in-memory (PostgreSQL in the works)
  • More pieces:
    • Axiom
    • ROM::Relation
    • ROM::Mapper
    • ROM::Session
    • Model
  • Identity Map

Perpetuity

  • Worth looking at
  • Simple
  • Implements the Data Mapper patter
  • Supports MongoDB, PostgreSQL, in-memory
  • Identity Map

Mongoid and MongoMapper

  • See Sarah Mei's essay on why to avoid MongoDB in most cases
  • Mongoid
    • Pretty simple
    • Be sure to turn on MongoDB persistence!
    • Pretty stable
  • TODO: Why to avoid MongoMapper

Mince

  • Simple and light-weight (no relations)
  • Supports MongoDB, Hashy (in-memory), and DynamoDB
  • Multi-tier architecture
    • Collections and items
    • Causes some un-DRYness declaring fields
  • No further development (last updated 2013-06-07)
	require 'mince'

	class BookDataModel
	  include Mince::DataModel
	  data_collection :books
	  data_fields :title, :publisher
	end

	class Book
	  include Mince::Model
	  data_model BookDataModel
	  fields :title, :publisher
	end

	book = Book.new title: 'The World In Photographs', publisher: 'National Geographic'
	book.save

Others

  • Swift
  • ORM Adapter
    • Gives a standard API, sitting atop AR, DM, MM, or Mongoid

NoORM

  • POROs
  • Sometimes you don't need persistence for all your models
    • TODO: Show examples
  • MagLev

The Future

  • ROM will reach 1.0 and be usable in production
  • Hopefully ROM will become the go-to ORM many cases
  • Perpetuity might become useful before ROM
  • MageLev might gather a following
  • Virtus::ActiveRecord might be a stepping-stone to ROM
  • ActiveRecord will continue to improve
  • We'll learn how to better use ActiveRecord

References

@maciejczyzewski

This comment has been minimized.

Copy link

commented Sep 6, 2014

Thx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.