rom-rb / rom

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

New settings api #651

Closed solnic closed 2 years ago

solnic commented 2 years ago

This replaces class-level config values with a new settings API powered by dry-configurable. All components have explicit settings defined now and there's a backward-compatibility shim added to rom/compat which makes sure that old-way of configuring classes through class attributes still works.

Here's how the default Relation settings look like:

    setting :auto_map, default: true
    setting :auto_struct, default: false
    setting :struct_namespace, default: ROM::Struct
    setting :wrap_class, default: Relation::Wrap

    setting :component do
      setting :id, default: :relation
      setting :dataset
      setting :adapter
      setting :gateway, default: :default
      setting :inflector, default: Inflector
    end

    setting :schema do
      setting :constant, default: Schema
      setting :dsl_class, default: Schema::DSL
      setting :attr_class, default: Attribute
      setting :inferrer, default: Schema::DEFAULT_INFERRER
    end

There's actually a very strict convention behind this grouping:

On top of this, both class definitions and DSL usage is expected to work consistently when it comes to handling configuration settings and DSL options are now automatically translated to component configs.

For example, defining a component class vs defining a component via DSL ends up with the exact same config:

irb(main):017:1* class Users < ROM::Relation[:memory]
irb(main):018:0> end
irb(main):019:0> config = ROM::Configuration.new(:memory)
irb(main):020:0> config.relation(:users)
irb(main):021:0> config.components.get(:relations, id: :users).constant
=> ROM::Relations::Users
irb(main):022:0> config.components.get(:relations, id: :users).constant.config.component
=> #<Dry::Configurable::Config values={:id=>:users, :dataset=>:users, :adapter=>:memory, :gateway=>:default, :inflector=>#<Dry::Inflector>}>
irb(main):023:0> Users.config.component
=> #<Dry::Configurable::Config values={:id=>:users, :dataset=>:users, :adapter=>:memory, :gateway=>:default, :inflector=>#<Dry::Inflector>}>