Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Generic Component API#650

Merged
solnic merged 5 commits intomasterfrom
generic-component-dsl
Jul 6, 2021
Merged

Generic Component API#650
solnic merged 5 commits intomasterfrom
generic-component-dsl

Conversation

@solnic
Copy link
Member

@solnic solnic commented Jul 4, 2021

This adds a generic component API which is the culmination of all the previous refactorings/improvements/cleanups. There's still a lot of additional complexity caused by backward-compatiblity but this will be cleaned up and moved to rom/compat eventually.

The important part is that IT WORKS 😆

Up until now, setting up rom could be a challenge, reasons were plenty and due to various limitations caused by the internals, it was hard to make it better. All the limitations are removed now and the entire system is way, way, WAY more flexible to the point that I can't even believe that it was possible.

Anyhow, the main idea behind rom-rb was always to be a toolkit that consists of a bunch of decoupled components that can be put together. It should be easy to use rom-rb for simple stuff, but it should be also easy to use rom-rb for advanced stuff.

Following this huge goal, this PR enables using rom-rb as if it was "Lego for persistence". You can start with a single class and define everything you need there and because most components can be inferred, this can be automated in 99%.

Examples

UPDATE: this particular API was extracted into a separate branch because this PR would become too big (it's already huge).

Here's an example of defining a custom class that is rom-enabled and it defines a relation with its schema explicitly. We auto_migrate so that the db schema is established automatically for us. Everything else is fully dynamic and automated:

require "rom"
require "rom/sql"

class Repo
  extend ROM(:sql, "sqlite::memory", as: :db)

  relation(:users) do
    schema do
      attribute :id, ROM::Types::Integer
      attribute :name, ROM::Types::String

      primary_key :id
    end
  end

  def create_user(params)
    relations[:users].changeset(:create, params).commit
  end
end

# this...just...works
repo = Repo.new

# and this is really cool
repo.gateways[:default].auto_migrate!(repo.db, inline: true)

# and this is some standard rom stuff, by default no struct mapping but this can be easily enabled
repo.create_user(name: "Jane").inspect
# {:id=>1, :name=>"Jane"}

Eventually, you'll be able to define any component type like that and either use your standalone rom-enabled objects, or provide a single rom setup like you used to.

@solnic solnic changed the title Move ConfigurationDSL to Components::DSL Generic Component API Jul 5, 2021
solnic added 4 commits July 6, 2021 12:57
There's a lot of complicated logic here in order to maintain backward
compatibility. It's possible to isolate this completely in rom/compat
though, which is what I'll do before 6.0.0 release.

In general, components will be able to provide their default config
using a very simple interface, so it will be completely generic.

Basically as long as a component responds to `config` method and it
returns a Hash-like object, then default settings will be resolved
automatically. All the class attributes will be replaced by this and
moved to rom/compat.
@solnic solnic force-pushed the generic-component-dsl branch from 7b48548 to 1c5efaf Compare July 6, 2021 13:07
@solnic solnic marked this pull request as ready for review July 6, 2021 13:13
@solnic solnic merged commit 9ef3ad9 into master Jul 6, 2021
@solnic solnic deleted the generic-component-dsl branch July 6, 2021 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant