Last active
March 18, 2022 10:19
-
-
Save mpressen/4270ef0184f2827100e303e74cd0d853 to your computer and use it in GitHub Desktop.
Polymorphic Joins
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
there's a better way, see other gist : https://gist.github.com/mpressen/73e0b8dd40be7775a45f88ec72cf6674