Thank you for creating such an amazing tool. I appreciate the separation of concerns! I can change the underlying db from mysql to pg to sqlite memory via only simple config changes - amazing!!!
I’m running into an issue where a relation command sometimes passes a hash to the mapper and sometimes passes the hash wrapped in an array causing a rom crash.
Here are the two relations and mapper involved (note one of the names is not pluralized)
module Relations
class RangeEachYear < ROM::Relation[:sql]
gateway :default
schema "#{ENV["DB_TABLE_PREFIX"]}_range_each_year".to_sym, infer: true, as: :range_each_year do
associations do
belongs_to :temporal_set_expressions
end
use :timestamps, attributes: %i[created_at created_at]
end
end
end
module Relations
class TemporalSetExpressions < ROM::Relation[:sql]
gateway :default
schema "#{ENV["DB_TABLE_PREFIX"]}_temporal_set_expressions".to_sym, infer: true, as: :temporal_set_expressions do
attribute :type, Types::Strict::String.enum(
'Union',
'Intersection',
'Difference')
associations do
has_many :range_each_year
end
use :timestamps, attributes: %i[created_at created_at]
end
end
end
module Mappers
class TemporalSetExpressionsMapper < ROM::Transformer
relation :temporal_set_expressions
register_as :temporal_set_expressions_mapper
map do
reject_keys [:foobar]
end
end
end
I get the relation and create 3 commands, one with combine, one with mapper, and one with both…
tse_rel = MyApp.container.relations[:temporal_set_expressions]
# cmd with combine
cmd_c = tse_rel.combine(:range_each_year)
.command(:create, use: :timestamps, plugins_options: {timestamps: {timestamps: %i[created_at updated_at]}})
# cmd with mapper
cmd_m = tse_rel
.command(:create, mapper: :temporal_set_expressions_mapper, use: :timestamps, plugins_options: {timestamps: {timestamps: %i[created_at updated_at]}})
# cmd with combine and mapper
cmd_cm = tse_rel.combine(:range_each_year)
.command(:create, mapper: :temporal_set_expressions_mapper, use: :timestamps, plugins_options: {timestamps: {timestamps: %i[created_at updated_at]}})
Below is the results of calling each command with data to create:
> cmd_c.call(parent_id: nil, type: 'Union', range_each_year: [])
=> {:type=>"Union", :created_at=>2022-03-25 16:22:15 -0400, :id=>1, :parent_id=>nil, :updated_at=>2022-03-25 16:22:15 -0400, :range_each_year=>[]}
> cmd_m.call(parent_id: nil, type: 'Union', range_each_year: [])
=> {:type=>"Union", :created_at=>2022-03-25 16:22:17 -0400, :id=>2, :parent_id=>nil, :updated_at=>2022-03-25 16:22:17 -0400}
> cmd_cm.call(parent_id: nil, type: 'Union', range_each_year: [])
.../gems/transproc-1.1.1/lib/transproc/hash.rb:212: warning: wrong element type Hash at 0 (expected array)
.../gems/transproc-1.1.1/lib/transproc/hash.rb:212: warning: ignoring wrong elements is deprecated, remove them explicitly
.../gems/transproc-1.1.1/lib/transproc/hash.rb:212: warning: this causes ArgumentError in the next release
ArgumentError: invalid number of elements (0 for 1..2)
.../gems/transproc-1.1.1/lib/transproc/hash.rb:212:in `[]'
I investigated to find the following:
211: def self.reject_keys(hash, keys)
=> 212: require 'pry'; binding.pry;
213: Hash[hash].reject { |k, _| keys.include?(k) }
214: end
[1] pry(Transproc::HashTransformations)> hash
=> [{:type=>"Union", :created_at=>2022-03-25 16:39:04 -0400, :id=>1, :parent_id=>nil, :updated_at=>2022-03-25 16:39:04 -0400}]
Why is the combination of mapper + combine on the create command returning an array?
What is the mistake I am making or what workaround can I use?
Many Thanks!!!