rom-rb / rom

Data mapping and persistence toolkit for Ruby
https://rom-rb.org
MIT License
2.07k stars 161 forks source link

Refactor setup/finalization #637

Closed solnic closed 3 years ago

solnic commented 3 years ago

This is a new implementation of the setup/configure/finalize code which drastically simplifies internals and makes it possible to easily extend ROM with more component types. This could be simplified further but a prerequisite is to simplify command compiler first, which I'll most likely do in a separate PR.

This is meant to be backward compatible, I'll test it out with other adapters and apps to ensure things work.

Here's a simple example of how things work internally now:

> config = ROM::Configuration.new(:memory)
# => #<ROM::Configuration:0x00007fdbd5fc3e70

> config.relation(:users)
# => ROM::Relation[Users]

> relation_component = config.components.relations.first
# => [#<ROM::Components::Relation:0x00007fdbd5f13070 @constant=ROM::Relation[Users], @key=:users>]

> ROM.with_configuration(config) { relation_component.build }
# => #<ROM::Relation[Users] name=ROM::Relation::Name(users) dataset=#<ROM::Memory::Dataset data=[]>>

This is a gigantic improvement because it demystifies how rom loads its components and isolates component-specific setup/build code in dedicated component classes. It opens up doors to a lot of interesting features that we'll be able to add later. ie using different configurations for the same component, providing pre-configured components from "the outside" (ie a bunch of preconfigured relations provided by a gem) and so on, lots of possibilities.

A quick follow-up after this is merged will be adding Components::Struct and Components::Repository - making them 1st-class core components that are easy to set up and use.

I will also make ROM's container 100% compatible with dry-system/hanami2 so that things like my_container.import(persistence: rom_container) will work OOTB.

Refs #607