Skip to content

Instantly share code, notes, and snippets.

@mpressen
Last active March 18, 2022 10:19
Show Gist options
  • Save mpressen/4270ef0184f2827100e303e74cd0d853 to your computer and use it in GitHub Desktop.
Save mpressen/4270ef0184f2827100e303e74cd0d853 to your computer and use it in GitHub Desktop.
Polymorphic Joins
# frozen_string_literal: true
class Model < ApplicationRecord
extend PolymorphicJoins
belongs_to :profile, polymorphic: true # can be Client::Profile or Freelancer::Profile models
scope :clients, -> { polymorphic_joins(Client::Profile) }
end
# frozen_string_literal: true
module PolymorphicJoins
def polymorphic_joins(model, prefix: find_prefix, join_type: 'INNER')
target_table = model.table_name
sql = <<~SQL.squish
#{join_type} JOIN #{target_table}
ON #{target_table}.id = #{table_name}.#{prefix}_id
SQL
joins(sql).where("#{prefix}_type": model.to_s)
end
private
def find_prefix
prefix = column_names.find { |col| col.ends_with?('_type') }
&.delete_suffix('_type')
unless prefix && column_names.find { |col| col == "#{prefix}_id" }
raise NoPolymorphismError, "#{name} doesn't have any polymorphic associations"
end
prefix
end
class NoPolymorphismError < StandardError; end
end
@mpressen
Copy link
Author

mpressen commented Mar 18, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment