Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

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

オープン
#280 コメント 0 件 リアクション 1 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
35/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
ruby, sql, sqlite
領域
database

調査の方向性

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.

索引モデルが issue の本文から書いたものです。

説明

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)

主要言語
Ruby
スター
220
フォーク
97
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

rom-rb/rom-sql のほかの issue

rom-rb/rom-sql の issue をすべて見る

似ている issue

Ruby の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。