rom-rb / rom

Data mapping and persistence toolkit for Ruby
https://rom-rb.org
MIT License
2.07k stars 161 forks source link

Fix multiple association block use to prevent ROM::AssociationSet registry error #683

Open bkuhlmann opened 1 year ago

bkuhlmann commented 1 year ago

Describe the bug

Hello. :wave: I ran into an issue that tripped me up due the error being rather confusing to debug:

rom-core-5.3.0/lib/rom/registry.rb:91:in `block in fetch': :account doesn't exist in ROM::AssociationSet[:integrations] registry (ROM::ElementNotFoundError)

In hindsight, the error makes a bit more sense now but when seeing it for the first time it took a while to realize that multiple association blocks won't work (which was an accident on my part due to being too hasty).

To Reproduce

Here's the inline script I used to reproduce (extracted from my Hanami application):

Script ``` ruby #! /usr/bin/env ruby # frozen_string_literal: true # Save as `snippet`, then `chmod 755 snippet`, and run as `./snippet`. require "bundler/inline" gemfile true do source "https://rubygems.org" gem "amazing_print" gem "debug" gem "pg" gem "rom" gem "rom-sql" gem "sequel" end class Account < ROM::Relation[:sql] schema :accounts, infer: true end class Provider < ROM::Relation[:sql] schema :providers, infer: true end class Integration < ROM::Relation[:sql] schema :integrations, infer: true do associations { belongs_to :account } associations { belongs_to :provider } end end configuration = ROM::Configuration.new :sql, "" [Account, Provider, Integration].each { |relation| configuration.register_relation relation } container = ROM.container configuration repository = ROM::Repository.new container puts repository.integrations.combine(:account).to_a.inspect ```
Error ``` /Users/bkuhlmann/.cache/frum/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rom-core-5.3.0/lib/rom/registry.rb:91:in `block in fetch': :account doesn't exist in ROM::AssociationSet[:integrations] registry (ROM::ElementNotFoundError) from /Users/bkuhlmann/.cache/frum/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rom-core-5.3.0/lib/rom/registry.rb:88:in `fetch' from /Users/bkuhlmann/.cache/frum/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rom-core-5.3.0/lib/rom/registry.rb:88:in `fetch' from /Users/bkuhlmann/.cache/frum/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rom-core-5.3.0/lib/rom/relation.rb:288:in `node' from /Users/bkuhlmann/.cache/frum/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rom-core-5.3.0/lib/rom/support/memoizable.rb:50:in `block (2 levels) in define_memoizable_names!' from /Users/bkuhlmann/.cache/frum/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rom-core-5.3.0/lib/rom/relation.rb:271:in `block in nodes' from /Users/bkuhlmann/.cache/frum/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rom-core-5.3.0/lib/rom/relation.rb:268:in `each' from /Users/bkuhlmann/.cache/frum/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rom-core-5.3.0/lib/rom/relation.rb:268:in `reduce' from /Users/bkuhlmann/.cache/frum/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rom-core-5.3.0/lib/rom/relation.rb:268:in `nodes' from /Users/bkuhlmann/.cache/frum/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rom-core-5.3.0/lib/rom/relation.rb:252:in `combine' from /Users/bkuhlmann/.cache/frum/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rom-core-5.3.0/lib/rom/support/memoizable.rb:50:in `block (2 levels) in define_memoizable_names!' from /Users/bkuhlmann/Engineering/Misc/snippet:43:in `
' ```

Expected behavior

I guess I would have expected to see an error like "multiple association blocks detected, there can be only one" or something along those lines. 😅

The solution is to use:

associations do
  belongs_to :account
  belongs_to :provider
end

Instead of:

associations { belongs_to :account }
associations { belongs_to :provider }

Maybe if multiple association blocks are detected, a better error could be provided? This isn't a huge priority but more of a nice to have I suppose.

My environment

solnic commented 1 year ago

Thanks for reporting this. I think it just works in main but I need to double check, so leaving this open but targeting 6.0.