This document provides an overview of ROM, a persistence and mapping toolkit for Ruby. It discusses ROM's core concepts like configurations, relations, commands, and mappers. It also summarizes ROM's history, community, and the ideas behind its design like reduced global state and immutability. Pros highlighted include flexibility in choosing data stores and combining data from different sources. Cons mentioned are a lack of documentation and commands not being fully supported in repositories yet.
3. What is ROM
(Ruby Object Mapper)
https://github.com/orgs/rom-rb
PERSISTENCE & MAPPING
TOOLKIT FOR RUBY
http://rom-rb.org
4. Author of ROM
Piotr Solnica | @_solnic_ | http://solnic.eu
author of ROM, Virtus, Dry-*, Rodakase, ...
5. Community
• dozen of devs
• very active Gitter channel
https://gitter.im/rom-rb/chat
• stable API >1.0v
• battle tested on production
6. History of ROM
• successor of DataMapper - aka DataMapper v2
• first commit - Feb 1 2012
• first version - v0.1 - Jun 15 2013
• first public version - v0.6 - Mar 22, 2015
• v1.0 - stable API - Jan 6, 2016
7. Core ideas
• reduced global state to minimum
• immutability
• mix OO with FP
• blazing fast
18. Pipelines
(everything that responds to #call
can be a mapper)
only_name = -> input { input.map{|u| u[:name]} }
upcase = -> input { input.map{|x| x.upcase} }
users = rom.relation(:users)
result = users >> only_name >> upcase
result.to_a
> ["JANE", "JACK"]
19. Domain data types &
Repositories
class User < Dry::Types::Value
attribute :name, Types::Strict::String
end
class UserRepo < ROM::Repository
relation :users
def all
users.select(:name).as(User).to_a
end
end
25. Request cycle
ParamsObject >> Validator >> ROM >>
Mapper(s) >> JSON API Mapper
Mapping &
coercion layer
Mapping &
coercion layer
combine
(or change)
data
convert data to
json api format
CQRS
26. combining data
class UserRepository < ROM::Repository::Base
relations :users, :tasks
def with_tasks(id)
users.by_id(id).combine_children(many: tasks)
end
end
user_repo.with_tasks.to_a
# [#<ROM::Struct[User] id=1 name="Jane" tasks=[#<ROM::Struct[Task] id=2
user_id=1 title="Jane Task">]>, #<ROM::Struct[User] id=2 name="Jack"
tasks=[#<ROM::Struct[Task] id=1 user_id=2 title="Jack Task">]>]
27. pros
• separating persistence from application &
encouraging that boundary
• ability to choose appropriate storage (SQL, NoSQL, ...),
but keeping the same API
• possibility to pull from different data sources,
and combine everything together
28. pros
• easy way to map (manipulate, coerce) data
• freedom
• community
29. cons
• commands (right now repository do not support them,
force to use very low level API, should be done before v2)
• hard to learn (many new concepts)
• lack of documentation (community will help you)
(currently community works to fix it, and there is always
someone sitting on Gitter to help you)