Need to override combine_keys with whatever in order to combine result correctly

Abierto
#280 0 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
35/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
ruby, sql, sqlite
Área
database

Línea de trabajo

Start with the provided ROM container reproduction and UserRepo#by_id, focusing on the users association and .combine(:buildings) path. Compare the empty result with the result produced when combine_keys is supplied. Done means the association combines the two buildings correctly without requiring an arbitrary combine_keys override, while preserving the shown reproduction behavior.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

bug unconfirmed

Using the gist provided below, ROM doesn't combine buildings correctly. The query result is empty even though the SQL query was correct.

[
  #<ROM::Struct::User id=1 login="[email protected]" employee_id=5 buildings=[]>
]

However, if you will modify the association

has_many :buildings, override: true, view: :for_user

and override combine_keys with literally whatever:

has_many :buildings, override: true, view: :for_user, combine_keys: {blah: :blah} # combine_keys: {} is also fine

it will work:

[
  #<ROM::Struct::User id=1 login="[email protected]" employee_id=5 
     buildings=[#<ROM::Struct::Building id=1 name="wew">, #<ROM::Struct::Building id=2 name="weeew">]>
]

Gist to reproduce:

rom = ROM.container(:sql, 'sqlite::memory') do |conf|
  conf.gateways[:default].use_logger(Logger.new($stdout))

  conf.default.create_table(:users) do
    primary_key :id
    column :login, String
  end

  conf.default.create_table(:employees) do
    primary_key :id
    column :name, String, null: false
  end

  conf.default.create_table(:buildings_employees) do
    foreign_key :building_id, :buildings
    foreign_key :employee_id, :employees
  end

  conf.default.create_table(:buildings) do
    primary_key :id
    column :name, String, null: false
  end

  conf.default.create_table(:employees_users) do
    foreign_key :verifable_id, :employees
    foreign_key :user_id, :users
  end

  conf.relation(:users) do
    schema(:users, infer: true) do
      associations do
        has_many :employees_users
        has_many :users, through: :employees_users
        has_many :buildings, override: true, view: :for_user
      end
    end
  end

  conf.relation(:employees) do
    schema(:employees, infer: true) do
      associations do
      end
    end
  end

  conf.relation(:buildings) do
    schema(:buildings, infer: true) do
      associations do
        has_many :buildings_employees
      end
    end

    def for_user(_assoc, users)
      join(:buildings_employees)
        .where(employee_id: users.pluck(:employee_id))
    end
  end

  conf.relation(:buildings_employees) do
    schema(:buildings_employees, infer: true) do
      associations do
        belongs_to :building
        belongs_to :employee
      end
    end
  end

  conf.relation(:employees_users) do
    schema(:employees_users, infer: true) do
      associations do
        belongs_to :user, foreign_key: :user_id
        belongs_to :employee, foreign_key: :verifable_id
      end
    end
  end
end

class UserRepo < ROM::Repository[:users]
  def by_id(id)
    users
      .join(:employees_users)
      .join(:employees, { id: :verifable_id })
      .select_append { |r| r[:employees][:id].as(:employee_id) }
      .combine(:buildings)
      .to_a
  end
end

employee = rom.relations[:employees].changeset(:create, name: 'Jane', id: 5).commit
rom.relations[:employees].changeset(:create, name: 'Jane', id: 8).commit

user = rom.relations[:users]
  .changeset(:create, login: '[email protected]')
  .commit

rom.relations[:employees_users]
  .changeset(:create, user_id: user[:id], verifable_id: employee[:id]).commit

au = rom.relations[:buildings]
  .changeset(:create, employee_id: employee[:id], name: 'wew').commit

au2 = rom.relations[:buildings]
  .changeset(:create, name: 'weeew').commit

rom.relations[:buildings_employees].changeset(
  :create,
  [
    { employee_id: employee[:id], building_id: au[:id] },
    { employee_id: employee[:id], building_id: au2[:id] }
  ]
).commit

repo = UserRepo.new(rom)

user = repo.by_id(1)

Bundled with:
rom-sql (2.3.0)

Lenguaje dominante
Ruby
Estrellas
220
Forks
97
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de rom-rb/rom-sql

Todos los issues de rom-rb/rom-sql

Issues similares

Más issues de Ruby

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.