whysthatso

Sort by attributes in nested, polymorphic model relations

Posted on September 30, 2024  //  rails

This is the relationship i have:

Portfolio.shares.coin.latest_value_snapshot.value_snapshot

I searched for a way when viewing a single portfolio to order shares by their latest value snapshot’s usdt value. This is the query i eventually came up with:

Portfolio
.includes(
{shares: {coin: {latest_value_snapshot: :value_snapshot}}},
{latest_value_snapshot: :value_snapshot},
{shares: {latest_value_snapshot: :value_snapshot}}
)
.joins(shares: {latest_value_snapshot: :value_snapshot})
.where(value_snapshots: {valueable_type: "Share"})
.order("value_snapshots.usdt_satoshis")
.find(params[:id])

For the polymorphic part, the key ingredient is .where(value_snapshots: {snapshotable_type: 'Share'}). This ensures that only the value_snapshots that are associated with Share are considered, filtering out those related to Portfolio or Coin. These have their own value snapshots.

The includes is related to eager loading, preventing N+1 query issues.

The explicit joins method helps creating the SQL join which help focusing the where condition and order method onto the value_snapshots table correctly.

The order method then applies to the usdt_satoshis table. Note that I am using the money gem to handle currencies, with USDT / Satoshis being a custom currency, hence the table name including the _satoshis prefix.

Hey! I'll happily receive your comments via email. Thanks for reading.

Andreas Wagner
freelance System Administrator and Ruby programmer in Tallinn, Estonia