Sort by attributes in nested, polymorphic model relations
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.