Skip to content
Yoko Harada edited this page Nov 10, 2013 · 1 revision

The Entity module is interesting, in that it is primarily made of pure functions that take their receiver (an instance of the class they are included in) and return data that you can use in Datomic. This makes it not an ORM-like thing at all, but instead a Ruby-ish data builder for Datomic. And yet, a Diametric::Entity is fully ActiveModel compliant! You can use them anywhere you would use an ActiveRecord model or another ActiveModel-compliant instance.

They do not include all ActiveModel modules by default, only the ones needed to establish compliance. You may want to include others yourself, such as Validations or Callbacks.

require 'diametric'

class Person
  include Diametric::Entity

  attribute :name, String, :index => true
  attribute :email, String, :cardinality => :many
  attribute :birthday, DateTime
  attribute :iq, Integer
end

# To see what schema data will be produced:
Person.schema

# The schema will be mapped to Datomic transaction data below:
# [{:db/id #db/id[:db.part/db]
#   :db/ident :person/name
#   :db/valueType :db.type/string
#   :db/cardinality :db.cardinality/one
#   :db/index true
#   :db.install/_attribute :db.part/db}
#  {:db/id #db/id[:db.part/db]
#   :db/ident :person/email
#   :db/valueType :db.type/string
#   :db/cardinality :db.cardinality/many
#   :db.install/_attribute :db.part/db}
#  {:db/id #db/id[:db.part/db]
#   :db/ident :person/birthday
#   :db/valueType :db.type/instant
#   :db/cardinality :db.cardinality/one
#   :db.install/_attribute :db.part/db}
#  {:db/id #db/id[:db.part/db]
#   :db/ident :person/iq
#   :db/valueType :db.type/long
#   :db/cardinality :db.cardinality/one
#   :db.install/_attribute :db.part/db}]

# To check what attributes are in Person model:
Person.attributes.keys
# [:dbid, :name, :email, :birthday, :iq]

# To create an instance from a query result
person = Person.new(Hash[*(Person.attributes.zip(results_from_query).flatten)])
# or
person = Person.from_query(results_from_query)

# To update/set values of a model:
person.iq = 180

# Below will help to understand what transaction data will be produced:
person.tx_data(:iq)

# It will be mapped to the Datomic transaction data:
# [{:db/id person.dbid
#   :person/iq 180}]

# To create new model instance:
person = Person.new(:name => "Peanut")
person.tx_data
# Datomic transaction data will be:
# [{:db/id #db/id[:db.part/user]
#   :person/name "Peanut"}]

In addition to attribute, Diametric supports enum type. This is often used on Datomic. For details, see Seattle Example