I have JSONB columns in my entities. Before, reading them by Hanami::Model, resulted in a hash. After switching to ROM, the column read from DB returns JSON.
# Before (Hanami::Model)
message.payload
# => { author: "Jsmith", content: "My message" }
# After (ROM 5.0)
# frozen_string_literal: true
module Entities
class Message < ROM::Struct
end
end
# frozen_string_literal: true
module Persistence
module Relations
class Messages < ROM::Relation[:sql]
schema(:messages, infer: true)
auto_struct true
end
end
end
class MessageRepository < Rom::Repository[:messages]
end
MessageRepository.new.messages.first.payload
# => "{\"author\":\"Jsmith\",\"content\":\"My message\"}"
Question: How I should configure a Mapper for all JSONB columns in my system at once?
#!/usr/bin/env ruby
require 'bundler/inline'
gemfile(true) do
source 'https://rubygems.org'
gem 'pg'
gem 'sequel_pg', require: 'sequel'
gem 'rom', '~> 5'
gem 'rom-sql'
end
require 'open3'
o, e, s = Open3.capture3("psql -c 'CREATE DATABASE rom_example'")
s.success? ? puts(o) : abort(e)
o, e, s = Open3.capture3('psql rom_example', stdin_data: <<~SQL)
CREATE schema public;
CREATE TABLE public.messages (
id bigint NOT NULL,
payload jsonb NOT NULL default '{}'
);
SQL
s.success? ? puts(o) : abort(e)
require 'sequel'
require 'rom'
require 'rom/sql'
ROM::SQL.load_extensions :postgres
config = ROM::Configuration.new(:sql, "postgres://localhost:5432/rom_example", extensions: %i[pg_json])
config.relation(:messages) do
schema(infer: true)
auto_struct true
end
rom = ROM.container(config)
relation = rom.relations[:messages]
attrs = { id: 1, payload: { author: "John Smith", content: "My message" } }
relation.changeset(:create, attrs).commit
message = relation.where(id: 1).one
puts "MESSAGE PAYLOAD: #{message.payload.inspect}"
rom.gateways[:default].disconnect
system "psql -c 'drop database rom_example'"
$ ./example.rb
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Using bundler 2.3.3
Using dry-initializer 3.1.1
Using method_source 1.0.0
Using pg 1.4.3
Using transproc 1.1.1
Using sequel 5.59.0
Using coderay 1.1.3
Using dry-inflector 0.3.0
Using ice_nine 0.11.2
Using concurrent-ruby 1.1.10
Using dry-equalizer 0.3.0
Using pry 0.14.1
Using sequel_pg 1.15.0
Using dry-core 0.8.1
Using dry-container 0.10.1
Using dry-logic 1.2.0
Using dry-types 1.5.1
Using dry-struct 1.4.0
Using rom-core 5.2.6
Using rom-changeset 5.2.3
Using rom-repository 5.2.2
Using rom 5.2.6
Using rom-sql 3.5.0
Expanded display is used automatically.
Null display is "¤".
CREATE DATABASE
Expanded display is used automatically.
Null display is "¤".
CREATE TABLE
MESSAGE PAYLOAD: {"author"=>"John Smith", "content"=>"My message"}
Expanded display is used automatically.
Null display is "¤".
DROP DATABASE
@alassek Thank you! It actually worked! It appears, I loaded extensions and plugins wrongly.
I experienced more problems, as the Sequel::Postgres::JSONHash returns stringified keys, while the rest of attributes symbolized and it can’t be stringified via: Hanami::Utils::Hash.deep_stymbolize(attrs)
I’ve handled that. However, I got stucked with other advanced query magic with Sequel and ROM mix :(.
I have a particular interest in SQL ASTs so this was an amusing diversion, although the software engineer in me wonders if this might be simpler to just implement as a database view.
This is complex so I’m going to take this a piece at a time.
SQL literals
There’s nothing wrong with using literals this way but there are Ruby interfaces for what you’re doing.
@swilgoszRelation#pluck is supposed to be used to return values from specific columns, it doesn’t support projected columns. You can probably skip pluck and just do .to_hash(:user_id, :featured_at).
BTW: I found that PG:: JSON returns stringified hash while the rest of Entities is accessible via symbolized hash. What would be the best way ro unify this?
I have written the custom type on top of PG::JSONB, but it requires me to define all JSONB columns in relations manually.
I’ve got a pet project I’m working on in my spare time that’s on Hanami 1.3.5. I’d be grateful if someone could point me to where I should start to upgrade it to 2.0? Is there any blog post or documentation?
Do you maybe have a WIP upgrade guide somewhere? I’d be interested in contributing to it as I’m trying to upgrade.
It currently doesn’t look good for Hanami to not have a an upgrade guide almost 4 months after the release. Especially with the link on the official guides page broken.
I agree, let’s join efforts to speed it up:). I have not yet freed up a dedicated day for OSS/content creation, still on my way to do so but things are progressing in the right direction:)
I’d be very happy to help! The project is a pet project so I work on it when I have time which is not often but I am hoping to update it to 2.0 over the next 2 months and I’ll be very happy to amend and extend a guide.
I can also start it from scratch but if there is anything already written it’s going to go much faster if I contribute to that.
@swilgosz you mentioned some notes you might share and that you already upgraded your models to ROM? Would it be possible to see the notes? I’ve picked up the upgrade of my (small) side project and I’m struggling a bit to switch from Hanami models to ROM since I haven’t used ROM on its own before.