ransack icon indicating copy to clipboard operation
ransack copied to clipboard

no such column error when sorting on deeply nested associations

Open dsusco opened this issue 1 year ago • 0 comments

I think I've stumbled upon a bug where the joins Ransack is creating to search associations aren't being aliased while sort_link is assuming they are. I have the following models:

class Species < ApplicationRecord
  belongs_to :genus, inverse_of: :species, required: true
  has_one :clade, inverse_of: :species, through: :genus
end

class Genus < ApplicationRecord
  belongs_to :clade, inverse_of: :genera, required: true
  has_many :species, inverse_of: :genus, dependent: :restrict_with_error
end

class Clade < ApplicationRecord
  has_many :genera, inverse_of: :clade, dependent: :restrict_with_error
  has_many :species, inverse_of: :clade, through: :genera
end

I can search and sort in nearly every combination except in the following scenario. If I search by a Clade and then try to sort by Genus I get the following query which results in the no such column error:

SELECT
  "species".*
FROM
  "species"
  LEFT OUTER JOIN "genera" ON "genera"."id" = "species"."genus_id"
  LEFT OUTER JOIN "clades" ON "clades"."id" = "genera"."clade_id"
WHERE
  "clades"."name" LIKE '%1%'
ORDER BY
  "genera_species"."name" ASC LIMIT ? OFFSET ?

Is there a way I can tell Ransack to alias the joins so I get:

  LEFT OUTER JOIN "genera" AS "genera_species" ON "genera"."id" = "species"."genus_id"
  LEFT OUTER JOIN "clades" AS "clades_species" ON "clades"."id" = "genera"."clade_id"

I can get around this by adding a joins call to my search where I specify the SQL myself:

@q = Species.joins('LEFT OUTER JOIN "genera" AS "genera_species" ON "genera"."id" = "species"."genus_id"', 'LEFT OUTER JOIN "clades" AS "clades_species" ON "clades"."id" = "genera"."clade_id"')ransack(params[:q])

This means that the joins are always performed (even when not needed) and Ransack also throws its own joins in there as well so the query is effectively:

SELECT
  "species".*
FROM
  "species"
  LEFT OUTER JOIN "genera" ON "genera"."id" = "species"."genus_id"
  LEFT OUTER JOIN "clades" ON "clades"."id" = "genera"."clade_id"
  LEFT OUTER JOIN "genera" AS "genera_species" ON "genera_species"."id" = "species"."genus_id"
  LEFT OUTER JOIN "clades" AS "clades_species" ON "clades_species"."id" = "genera_species"."clade_id"
WHERE
  "clades"."name" LIKE '%1%' ORDER BY "genera_species"."name" ASC LIMIT ? OFFSET ?

dsusco avatar Apr 04 '23 15:04 dsusco