Skip to content

Conversation

swilgosz
Copy link

@swilgosz swilgosz commented Apr 5, 2022

Overview

Tweaks for Hanami 2 integration.

Background

During configuring of Hanami 2 project to work with RES-ROM in order to integrate ecommerce application RailsEventStore/ecommerce#110, I have encountered Sequel problem: sequel-error.txt. Command below accepts named arguments, so there is no way to call the command handler directly passing invalid parameters to it.

cmd = Crm::RegisterCustomer.new(customer_id: customer_id, name: name)
command_bus.(cmd)

However, calling command bus with this command returns an Sequel Error: Column not found (details below).

I have found that CreateEvents changeset receives Hash as a value for JSONB columns (data and metadata) in case of Hanami 2 integration, and String in Rails or tests.

To solve it, I added two additional MAP_VALUE rules.

module RubyEventStore
  module ROM
    module Changesets
      class CreateEvents < ::ROM::Changeset::Create
        relation :events

        map(&:to_h)
        map do
          # ...
          map_value   :data, ->(value) { value.class.name == "Hash" ? value.to_json : value }
          map_value   :metadata, ->(value) { value.class.name == "Hash" ? value.to_json : value }
          # ...
        end

        def commit
          relation.multi_insert(to_a)
        end
      end
    end
  end
end

It sems to solve the problem, but I am not happy with this as I believe, I did not find the source of the problem. I expect that some kind of value transformation was not triggered.

Additional notes

  1. I've noticed, that active support is only required in tests, so I moved it to the test group.
  2. Sequel Error logs: sequel-error.txt

Summary

I keep this PR as a monkey patch for now, until the proper fix is found, to make Hanami 2 integration possible. Help welcome!

Sebastian Wilgosz added 2 commits April 5, 2022 13:55
This is only relevant when running tests as i is only used in test configuration
Reason: In hanami integration, for some reason, I get hash instead of String in those two fields.
Possibly there is sth wrong with the configuration itself but just for now I added this quick fix.
gem "pg", ">= 1.2.2"
gem "ruby_event_store", path: "../../ruby_event_store"
gem "sqlite3", "1.4.2"
gem "activesupport"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gemfile is purely for test. We're not using bundler groups at all anywhere in the RES codebase.

You can have a look on ROM dependencies at:

spec.add_dependency "dry-container", ">= 0.6"
spec.add_dependency "dry-initializer", ">= 3.0"
spec.add_dependency "dry-types", ">= 1.0"
spec.add_dependency "rom-changeset", ">= 5.0"
spec.add_dependency "rom-repository", ">= 5.0"
spec.add_dependency "rom-sql", ">= 3.0"
spec.add_dependency "sequel", ">= 5.11.0"
spec.add_dependency "ruby_event_store", ">= 2.0.0", "< 3.0.0"

map_value :valid_at, ->(time) { Time.iso8601(time).localtime }
map_value :data, ->(value) { value.class.name == "Hash" ? value.to_json : value }
map_value :metadata, ->(value) { value.class.name == "Hash" ? value.to_json : value }
accept_keys %i[event_id data metadata event_type created_at valid_at]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps worth adding a test recreating the situation you've encountered?

@mostlyobvious
Copy link
Member

Long story short:

@mostlyobvious
Copy link
Member

mostlyobvious commented Apr 11, 2022

Can you first check that switching https://github.com/RailsEventStore/ecommerce/blob/6de6008878decfb4332a01e052202fb4a473bb4f/hanami_application/config/providers/event_repository.rb#L9 ::RubyEventStore::NULL to ::JSON works as expected?

@mostlyobvious
Copy link
Member

mostlyobvious commented Apr 11, 2022

Loudly thinking — if there's a way to pass ActiveRecord data/metadata as strings for json/jsonb columns, that do not get additional to-string serialization, that would greatly reduce complexity around serailizers for JSON across all known repositories. Same interface for all (as initially designed) — repository gets serialized-data-as-string and has to put it in right place, without insisting on serializing it once again (as AR does here).

@mostlyobvious
Copy link
Member

Btw. that SQL payload was the most valuable part of the exception as it shows data in raw shape as we insert it. Too bad it was trimmed.

Sequel::DatabaseError: PG::UndefinedColumn: ERROR:  column "customer_id" does not exist
LINE 1: ...VALUES ('d20c4621-3874-45d3-8a06-338dc6c969d8', (("customer_...

@mostlyobvious
Copy link
Member

Verified: RailsEventStore/ecommerce#110 (comment)

mostlyobvious added a commit to swilgosz/ecommerce that referenced this pull request Jun 22, 2022
RailsEventStore/rails_event_store#1297 (comment)

Co-authored-by: Paweł Świątkowski <katafrakt@users.noreply.github.com>
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.

2 participants