rom-rb / rom

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

Relation `join` method only returns columns of the relation running the `join`. #499

Closed calopez closed 6 years ago

calopez commented 6 years ago

VERSIONS

class User < ROM::Relation[:sql]
  schema(:users, infer: true) do
    associations do has_one :address end
  end
end

class Address < ROM::Relation[:sql]
  schema(:addresses, infer: true) do
    associations do belongs_to :user end
  end
end

ROM_ENV = ROM.container(:sql, 'sqlite::memory') do |config|
  gateway = config.gateways[:default]
  migration = gateway.migration do
    change do
      create_table :users do
        primary_key :id
        string :name, null: false
      end

      create_table :addresses do
        primary_key :id
        string :address_line_1, null: false
        foreign_key :user_id, :users
      end
    end
  end

  migration.apply(gateway.connection, :up)
  config.register_relation User
  config.register_relation Address
end

ROM::Relations Whe joining two relations only the columns of the relation running the join are returned. If I use assoc instead of join, only the columns of the joining relation are returned. If I use Sequel al columns are returned, which is the result I expect.

Reproducing the issue:

address = rom.relations[:addresses]
user = rom.relations[:users]

user.transaction do
   u = user.changeset(:create, name: 'carlos').commit  
   a = address.changeset(:create, address_line_1: 'Maxella 89 Av').associate(u, :users).commit   
end  
=> {:id=>1, :address_line_1=>"Maxella 89 Av", :user_id=>1}

user.join(:addresses).to_a
=> [{:id=>1, :name=>"carlos"}]

user.assoc(:addresses).to_a
=> [{:id=>1, :address_line_1=>"Maxella 89 Av", :user_id=>1}]

DB = rom.gateways[:default]
DB[:users].join(:addresses, { user_id: :id }).all
=> [{:id=>1, :name=>"carlos", :address_line_1=>"Maxella 89 Av", :user_id=>1}]
solnic commented 6 years ago

This is intended behavior. We use Sequel but it's an implementation detail, you should not have any expectations based on what Sequel does. The reason why we don't auto-append columns from a joined relation is pretty simple - you may have conflicting column names, and on top of that, auto-appending columns would be implicit behavior, we're trying to avoid that in rom in general.