-
-
Save carlisia/1269fa6680487b658c9f to your computer and use it in GitHub Desktop.
Q: "What are the minimum interfaces that my Adapter's Repository, Relation, and Dataset need to implement?"
A: "linter specs / tests that you can mixin to ensure you're providing the minimal interface (for an api adapter):"
https://github.com/rom-rb/rom/tree/master/lib/rom/lint
Q: "Where to register the custom adapter?"
A: "Typically the main adapter file does that, ie, https://github.com/rom-rb/rom-sql/blob/master/lib/rom/sql.rb#L30"
Q: "What is env
?"
A: "env
is rom’s object registry, it gets setup when you call ROM.finalize. So, after you defined and loaded all your classes, you call finalize and you get the registry under ROM.env
."
Q: "What do you do with Mappers?"
A: "You don't need Mappers. But, typically, people use mappers to turn that into something more “higher-level. It's how you map a relation to a Rails model, which is explicit in ROM. You always need to provide which mapper it should use, ie, rom.relation(:users).as(:entity) would send users through its entity mapper.
The interface was designed in a way that you should be able to memoize some relation and refer to it from other places so ie you’d do sth like @users = rom.relation(:users).as(:entity) and then @users.active.page(2) or something.
Q: "Why the .as(:entity)
?"
A: ".as(:entity)
means “send data through :entity
mapper (see: register_as :name -> .as(:name)
and tasks.index_view(params[:status]).as(:tasks)
)."
require 'rom'
ROM.setup(:memory)
class User
attr_reader :name, :age
def initialize(attributes)
@name, @age = attributes.values_at(:name, :age)
end
end
class Users < ROM::Relation[:memory]
def by_name(name)
restrict(name: name)
end
def adults
restrict { |user| user[:age] >= 18 }
end
end
class UserMapper < ROM::Mapper
relation :users
register_as :entity
model User
attribute :name
attribute :age
end
class CreateUser < ROM::Commands::Create[:memory]
register_as :create
relation :users
result :one
end
class UpdateUser < ROM::Commands::Update[:memory]
register_as :update
relation :users
result :one
end
rom = ROM.finalize.env
user1 = rom.command(:users).as(:entity).create.call(name: "Joe", age: 17)
user2 = rom.command(:users).as(:entity).update.set(name: "Jane", age: 18)
puts user1.class, user2.class # => User, Hash
Q: "What's a repository?"
A: ""Repository" is poorly named, as it doesn't actually reflect a repository pattern
the Adapter's repository is the class it uses to interact with whatever it's backend is
more of a gateway
thus, each adapter has 1 repository
but, what you register is an instance of an adapter
which in turn ends up with an instance of it's internal repository class"
Github API example: https://github.com/solnic/rom-demo/blob/master/lib/rom/github.rb