I'm trying out http://rom-rb.org/ and can't figure out how to get a presence validation to pass in the presence of multiple source models. I would expect the following script to save a new event and organiser, but instead it says that event_name is not present.
What am I missing?
require 'bundler/inline'
gemfile do
  source 'https://rubygems.org'
  gem 'rom'
  gem 'rom-sql'
  gem 'rom-rails'
  gem 'activemodel'
  gem 'sqlite3'
  gem 'activesupport'
end
require 'rom'
require 'rom-rails'
`rm -Rf /tmp/romtest.sqlite`
ROM.setup(:sql, 'sqlite:///tmp/romtest.sqlite')
class Events < ROM::Relation[:sql]
end
class Organisers < ROM::Relation[:sql]
end
class CreateEvent < ROM::Commands::Create[:sql]
  relation :events
  register_as :create
  result :one
  associates :organiser, key: [:organiser_id, :id]
end
class CreateOrganiser < ROM::Commands::Create[:sql]
  relation :organisers
  register_as :create
  result :one
end
class CreateEventWithOrganiser < ROM::Model::Form
  commands organisers: :create, events: :create
  input do
    attribute :email
    attribute :event_name
  end
  validations do
    validates :event_name, presence: true
  end
  def commit!
    command = organisers.create.with(
      email: email,
    ) >> events.create.with(
      name: event_name,
    )
    command.transaction do
      command.call
    end
  end
end
ROM.finalize
rom = ROM.env
gateway = rom.gateways.fetch(:default)
migration = gateway.migration do
  change do
    create_table :organisers do
      primary_key :id
      column :email, String, null: false
    end
    create_table :events do
      primary_key :id
      column :name, String, null: false
      column :organiser_id, Integer, null: false
    end
  end
end
migration.apply(gateway.connection, :up)
f = CreateEventWithOrganiser.build(
  email:      '[email protected]',
  event_name: 'Test Event'
)
# Unexpectedly fails
f.save
puts f.errors.full_messages
# => "Event name can't be blank"
 
                        
Here's an updated version of your script which works:
The reason why it didn't work with
commandsis because this method will generate command objects for your form and set provided validations for each command, which will only work correctly if you used a single command. Otherwise same validator is used for each command which doesn't make sense. When you useinject_commands_forit will grab your own commands where validators are not set so you are free to handle validations yourself.I think we should stop setting validators on commands which would make your original sample work but notice that you need to call
validate!yourself.I hope this helps.
I also created a gist showing how to do the same without a form: https://gist.github.com/solnic/3b68342482cf1414f719